diff options
Diffstat (limited to 'center_fw/main.c')
-rw-r--r-- | center_fw/main.c | 139 |
1 files changed, 93 insertions, 46 deletions
diff --git a/center_fw/main.c b/center_fw/main.c index a2c6eaa..71d3f00 100644 --- a/center_fw/main.c +++ b/center_fw/main.c @@ -30,11 +30,12 @@ void TIM1_BRK_UP_TRG_COM_Handler() { } void set_drv_gpios(uint8_t val) { - int a=!!(val&1), b=!!(val&2), c=!!(val&4), d=!!(val&8); - GPIOA->BSRR = ((!a<<3 | !b<<7 | c<<6 | d<<4)<<16) | (a<<3 | b<<7 | !c<<6 | !d<<4); + val = ~val; + int a=!(val&1), b=!(val&2), c=!(val&4), d=!(val&8); + GPIOA->BSRR = (((!a)<<3 | (!b)<<7 | (!c)<<6 | (!d)<<4)<<16) | ((a<<3) | (b<<7) | (c<<6) | (d<<4)); } -uint8_t out_state = 0x01; +uint8_t out_state = 0x0f; void set_outputs(uint8_t val[8]) { /* TODO implement BCM for digital brightness control */ int x = 0; @@ -56,111 +57,157 @@ void set_load(bool load) { } void blank(void) { + GPIOA->BRR = (1<<9) | (1<<10); set_drv_gpios(0); } -volatile int bit; /* FIXME */ -void unblank_low(void) { +bool has_sync = 0; +void unblank_low(int bit) { if (backchannel_frame) { /* Set from protocol.c */ if (tx_next_bit() == 1) set_load(1); else /* 0; but also TX_IDLE */ set_load(0); - } else { - if (bit) + } else if (has_sync) { + if (bit) { + //GPIOA->BSRR = (1<<10); set_drv_gpios(out_state & 0xf); - else + + } else { + //GPIOA->BSRR = (1<<9); set_drv_gpios(out_state >> 4); + } } } +int sync_ctr = 0xffff; void TIM3_IRQHandler(void) { - GPIOA->BSRR = 1<<10; /* debug */ - if (TIM3->SR & TIM_SR_UIF) - unblank_low(); - else + if (TIM3->SR & TIM_SR_CC2IF) { + if (sync_ctr > 10) + has_sync = 0; + else + sync_ctr += 1; + EXTI->IMR = (1<<0); + GPIOB->BSRR = (1<<1); + GPIOA->BRR = (1<<9) | (1<<10); + + } else if (TIM3->SR & TIM_SR_CC3IF) { + int bit = GPIOA->IDR & (1<<5); /* Sample current polarity */ + unblank_low(!bit); + + } else { blank(); + } TIM3->SR = 0; - GPIOA->BRR = 1<<10; /* debug */ +} + +void EXTI0_1_IRQHandler(void) { + static uint32_t jitter_meas_sum = 0, jitter_meas_cnt = 0; + EXTI->PR = (1<<0); + + /* Store old counter value for jitter measurement. Let it overflow to handle negative offsets. */ + int16_t cnt = (int16_t)TIM3->CNT; + /* Re-initialize the counter to align it with the signal edge */ + TIM3->EGR |= TIM_EGR_UG; + + /* Don't handle overflow of _sum here since this value is only for monitoring anyway */ + jitter_meas_sum += (cnt >= 0) ? cnt : -cnt; + if (++jitter_meas_cnt == 1000) { /* One measurement roughly every 800ms */ + jitter_meas_avg_ns = jitter_meas_sum; + } + + EXTI->IMR = 0; + GPIOB->BRR = (1<<1); + has_sync = 1; + sync_ctr = 0; } int main(void) { - RCC->CR |= RCC_CR_HSEON; - while (!(RCC->CR&RCC_CR_HSERDY)); + //RCC->CR |= RCC_CR_HSEON; + //while (!(RCC->CR&RCC_CR_HSERDY)); RCC->CFGR &= ~RCC_CFGR_PLLMUL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE_Msk & ~RCC_CFGR_HPRE_Msk; - RCC->CFGR |= ((6-2)<<RCC_CFGR_PLLMUL_Pos) | RCC_CFGR_PLLSRC_HSE_PREDIV; /* PLL x6 -> 48.0MHz */ + RCC->CFGR |= ((12-2)<<RCC_CFGR_PLLMUL_Pos); /* PLL / 2 * 12 -> 48.0MHz */ RCC->CR |= RCC_CR_PLLON; while (!(RCC->CR&RCC_CR_PLLRDY)); RCC->CFGR |= (2<<RCC_CFGR_SW_Pos); SystemCoreClockUpdate(); - //SysTick_Config(SystemCoreClock/1000); /* 1ms interval */ + SysTick_Config(SystemCoreClock/1000); /* 1ms interval */ /* Turn on lots of neat things */ - RCC->AHBENR |= RCC_AHBENR_DMAEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_FLITFEN; + RCC->AHBENR |= RCC_AHBENR_DMAEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_FLITFEN; RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN| RCC_APB2ENR_DBGMCUEN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM1EN;; RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; /* TIM3 foo */ TIM3->CCMR2 = (6<<TIM_CCMR2_OC4M_Pos); /* PWM Mode 1 to get a clean trigger signal */ TIM3->CCER = TIM_CCER_CC4E; /* Enable capture/compare unit 4 connected to ADC */ + TIM3->CCER = TIM_CCER_CC3E; /* Enable capture/compare unit 3 for unblank interrupt */ + TIM3->CCER = TIM_CCER_CC2E; TIM3->PSC = 48-1; /* 48MHz -> 1MHz */ - TIM3->CCR4 = 170-1; /* CC4 is ADC trigger, fire 30us before end of cycle. */ - TIM3->ARR = 200-1; /* 1MHz -> 5kHz */ + TIM3->CCR2 = 800-1-1; + TIM3->CCR3 = 100-1; /* CC3 is used for unblanking in the ISR, fires 30us after beginning of cycle. */ + TIM3->CCR4 = 800-100-1; /* CC4 is ADC trigger, fire 30us before end of cycle. */ + TIM3->ARR = 800-1; /* 1MHz -> 5kHz */ - TIM3->DIER |= TIM_DIER_UIE | TIM_DIER_CC4IE; + TIM3->DIER |= TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE | TIM_DIER_UIE; TIM3->CR1 |= TIM_CR1_CEN; NVIC_EnableIRQ(TIM3_IRQn); NVIC_SetPriority(TIM3_IRQn, 3<<5); + GPIOB->MODER |= (1<<GPIO_MODER_MODER1_Pos); + GPIOB->OSPEEDR |= (2<<GPIO_OSPEEDR_OSPEEDR1_Pos); + + EXTI->IMR = (1<<0); /* PA0 Vmeas_A for sync */ + EXTI->RTSR |= (1<<0); + NVIC_EnableIRQ(EXTI0_1_IRQn); + NVIC_SetPriority(EXTI0_1_IRQn, 4<<5); + GPIOA->MODER |= (0<<GPIO_MODER_MODER0_Pos) /* PA0 - Vmeas_A to ADC */ - | (0<<GPIO_MODER_MODER1_Pos) /* PA1 - Vmeas_B to ADC */ + | (0<<GPIO_MODER_MODER1_Pos) /* PA1 - Unused */ | (1<<GPIO_MODER_MODER2_Pos) /* PA2 - LOAD */ | (1<<GPIO_MODER_MODER3_Pos) /* PA3 - CH0 */ | (1<<GPIO_MODER_MODER4_Pos) /* PA4 - CH3 */ - | (1<<GPIO_MODER_MODER5_Pos) /* PA5 - TP1 */ + | (0<<GPIO_MODER_MODER5_Pos) /* PA5 - TP1 */ | (1<<GPIO_MODER_MODER6_Pos) /* PA6 - CH2 */ | (1<<GPIO_MODER_MODER7_Pos) /* PA7 - CH1 */ - | (1<<GPIO_MODER_MODER9_Pos) /* PA9 - TP2 */ - | (1<<GPIO_MODER_MODER10_Pos);/* PA10 - TP3 */ + | (1<<GPIO_MODER_MODER9_Pos) /* PA9 - synchronous rectifier bypass A */ + | (1<<GPIO_MODER_MODER10_Pos);/* PA10 - synchronous rectifier bypass B */ + + GPIOA->PUPDR |= (2<<GPIO_PUPDR_PUPDR5_Pos); /* Set shift register IO GPIO output speed */ GPIOA->OSPEEDR |= (2<<GPIO_OSPEEDR_OSPEEDR2_Pos) /* LOAD */ | (2<<GPIO_OSPEEDR_OSPEEDR3_Pos) /* CH0 */ - | (2<<GPIO_OSPEEDR_OSPEEDR4_Pos) /* CH3 */ + | (2<<GPIO_OSPEEDR_OSPEEDR4_Pos) /* CH3 */ | (2<<GPIO_OSPEEDR_OSPEEDR6_Pos) /* CH2 */ - | (2<<GPIO_OSPEEDR_OSPEEDR7_Pos); /* CH1 */ + | (2<<GPIO_OSPEEDR_OSPEEDR7_Pos) /* CH1 */ + | (2<<GPIO_OSPEEDR_OSPEEDR9_Pos) /* synchronous rectifier bypass A */ + | (2<<GPIO_OSPEEDR_OSPEEDR10_Pos); /* synchronous rectifier bypass B */ set_drv_gpios(0); protocol_init(); - uint32_t jitter_meas_sum = 0, jitter_meas_cnt = 0; + int cnt = 0; + int seg_c = 0; while (42) { - int new = GPIOA->IDR & (1<<0); /* Sample current polarity */ - if (new != bit) { /* Zero-crossing detected */ - bit = new; - - /* Store old counter value for jitter measurement. Let it overflow to handle negative offsets. */ - int16_t cnt = (int16_t)TIM3->CNT; - /* Re-initialize the counter to align it with the signal edge */ - TIM3->EGR |= TIM_EGR_UG; - /* Unblank since the update interrupt will not fire this time */ - unblank_low(); - - /* Don't handle overflow of _sum here since this value is only for monitoring anyway */ - jitter_meas_sum += (cnt >= 0) ? cnt : -cnt; - if (++jitter_meas_cnt == 4000) { /* One measurement roughly every 800ms */ - /* Divide aggregate over 4000 us-resolution measurements by 4 -> ns-resolution average */ - uint32_t divided = jitter_meas_sum>>2; - jitter_meas_avg_ns = (divided < UINT16_MAX) ? divided : UINT16_MAX; - } + /* + if (cnt > 10000) { + cnt = 0; + seg_c += 1; + if (seg_c == 8) + seg_c = 0; + set_outputs_binary(1<<seg_c, 255); + } else { + cnt = cnt+1; } + */ /* idle */ } } |