From d2194c5ae236700e8817efa8d0e843aad113d1fb Mon Sep 17 00:00:00 2001 From: jaseg Date: Sat, 9 Dec 2017 14:41:58 +0100 Subject: Fixed aux cycle --- fw/main.c | 105 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 55 insertions(+), 50 deletions(-) diff --git a/fw/main.c b/fw/main.c index 0aa7c32..610e16f 100644 --- a/fw/main.c +++ b/fw/main.c @@ -141,14 +141,6 @@ unsigned int stk_microseconds(void) { return sys_time*1000 + (1000 - (SysTick->VAL / (SystemCoreClock/1000000))); } -enum { - SPI_AUX, - SPI_WORD0, - SPI_WORD1, - SPI_IDLE, -} spi_state; -static volatile uint32_t spi_word = 0; - void cfg_spi1() { /* Configure SPI controller */ SPI1->I2SCFGR = 0; @@ -156,46 +148,23 @@ void cfg_spi1() { SPI1->CR2 &= ~SPI_CR2_DS_Msk; SPI1->CR2 |= LL_SPI_DATAWIDTH_16BIT; - /* Baud rate PCLK/2 -> 25MHz */ + /* Baud rate PCLK/4 -> 12.5MHz */ SPI1->CR1 = SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE - | (0<BSRR = GPIO_BSRR_BS_0; // Debug - switch (spi_state) { - case SPI_AUX: - strobe_aux(); - SPI1->DR = spi_word>>16; - break; - case SPI_WORD0: - SPI1->DR = spi_word&0xFFFF; - break; - default: - tick(); /* This one is important. Otherwise, weird stuff happens and parts of the aux register seem to leak - into the driver registers. */ - strobe_leds(); - SPI1->CR2 &= ~SPI_CR2_TXEIE; - break; - } - spi_state ++; - GPIOA->BSRR = GPIO_BSRR_BR_0; // Debug } uint8_t segment_map[8] = {5, 7, 6, 4, 1, 3, 0, 2}; +static volatile uint32_t aux_reg = 0; static volatile int frame_duration_us; volatile int nbits = MAX_BITS; /* returns new bit time in cycles */ @@ -213,9 +182,11 @@ int shift_data() { if (active_segment == NSEGMENTS) { active_segment = 0; + /* FIXME remove this? int time = stk_microseconds(); frame_duration_us = time - last_frame_time; last_frame_time = time; + */ if (fb_op == FB_UPDATE) { volatile struct framebuf *tmp = read_fb; read_fb = write_fb; @@ -224,17 +195,21 @@ int shift_data() { } } - spi_word = read_fb->data[active_bit*FRAME_SIZE_WORDS + active_segment]; - spi_state = SPI_AUX; - SPI1->DR = (read_fb->brightness ? SR_ILED_HIGH : SR_ILED_LOW) - | (led_state<<1) - | (0xff00 ^ (0x100<data[active_bit*FRAME_SIZE_WORDS + active_segment]; - spi_state = SPI_WORD0; - SPI1->DR = spi_word>>16; + GPIOA->BSRR = GPIO_BSRR_BR_10; + SPI1->DR = aux_reg | segment_map[active_segment]; + while (SPI1->SR & SPI_SR_BSY); + GPIOA->BSRR = GPIO_BSRR_BS_10; } - SPI1->CR2 |= SPI_CR2_TXEIE; + + uint32_t spi_word = read_fb->data[active_bit*FRAME_SIZE_WORDS + active_segment]; + SPI1->DR = spi_word>>16; + spi_word &= 0xFFFF; + while (!(SPI1->SR & SPI_SR_TXE)); + SPI1->DR = spi_word; + while (!(SPI1->SR & SPI_SR_TXE)); + //tick(); + //strobe_leds(); + // FIXME SPI1->CR2 |= SPI_CR2_TXEIE; return active_bit; } @@ -246,7 +221,9 @@ int shift_data() { /* This value is a constant offset added to every bit period to allow for the timer IRQ handler to execute. This is set * empirically using a debugger and a logic analyzer. */ -#define TIMER_CYCLES_FOR_SPI_TRANSMISSIONS 25 +#define TIMER_CYCLES_FOR_SPI_TRANSMISSIONS 21 + +#define TIMER_CYCLES_BEFORE_LED_STROBE 20 /* Defines for brevity */ #define A TIMER_CYCLES_FOR_SPI_TRANSMISSIONS @@ -288,14 +265,29 @@ void cfg_timer3() { * interrupt to load the next bits in to the shift registers. Channel 2 triggers simultaneously with channel 1 at * long !OE periods but will be delayed slightly to a fixed 32 timer periods (12.8us) to allow for SPI1 to finish * shifting out all frame data before asserting !OE. */ + TIM3->CR2 = (2<CCMR1 = (6<CCER = TIM_CCER_CC1E; /* Inverting output */ + TIM3->CCER = TIM_CCER_CC1E; + TIM3->CCR1 = TIMER_CYCLES_FOR_SPI_TRANSMISSIONS; TIM3->DIER = TIM_DIER_UIE; TIM3->PSC = SystemCoreClock/5000000 * 2 - 1; /* 0.20us/tick */ TIM3->ARR = 0xffff; TIM3->EGR |= TIM_EGR_UG; TIM3->CR1 = TIM_CR1_ARPE; TIM3->CR1 |= TIM_CR1_CEN; + + TIM1->SR = 0; + TIM1->BDTR = TIM_BDTR_MOE; + TIM1->SMCR = (2< TIM3; slave mode: reset */ + TIM1->CCMR1 = (6<CCER = TIM_CCER_CC2E; + TIM1->CCR2 = TIMER_CYCLES_BEFORE_LED_STROBE; + TIM1->PSC = TIM3->PSC; /* 0.20us/tick */ + TIM1->ARR = 0xffff; + TIM1->EGR |= TIM_EGR_UG; + TIM1->CR1 = TIM_CR1_ARPE; + TIM1->CR1 |= TIM_CR1_CEN; + NVIC_EnableIRQ(TIM3_IRQn); NVIC_SetPriority(TIM3_IRQn, 2); } @@ -305,7 +297,6 @@ void TIM3_IRQHandler() { //TIM3->CR1 &= ~TIM_CR1_CEN_Msk; FIXME int idx = shift_data(); - TIM3->CCR1 = TIMER_CYCLES_FOR_SPI_TRANSMISSIONS; TIM3->ARR = timer_period_lookup[idx]; TIM3->SR &= ~TIM_SR_UIF_Msk; @@ -418,7 +409,7 @@ int main(void) { SystemCoreClockUpdate(); RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_DMAEN | RCC_AHBENR_CRCEN | RCC_AHBENR_FLITFEN; - RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN | RCC_APB2ENR_DBGMCUEN; + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN | RCC_APB2ENR_DBGMCUEN | RCC_APB2ENR_TIM1EN; RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; GPIOA->MODER |= @@ -430,7 +421,7 @@ int main(void) { | (2<AFR[1] |= + (2<PUPDR |= (2<brightness = 1; for (int i=0; idata)/sizeof(uint32_t); i++) { @@ -473,7 +471,14 @@ int main(void) { adc_config(); volatile uint8_t *rxd = rx_buf.byte_data; + int k=0; while (42) { + aux_reg = (read_fb->brightness ? SR_ILED_HIGH : SR_ILED_LOW) | (led_state<<1); + if (k++ == 1000000) { + k = 0; + led_state = (led_state+1)&7; + } + if (USART1->ISR & USART_ISR_RXNE) { *rxd++ = USART1->RDR; if (rxd >= rx_buf.set_fb_rq.end) { @@ -508,6 +513,6 @@ void SysTick_Handler(void) { if (n++ == 1000) { n = 0; sys_time_seconds++; -} + } } -- cgit