From 570f527a3a4c4bd74bbbb174681a7c0e64e4b5b8 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 23 Aug 2017 14:11:45 +0200 Subject: Interrupt-driven SPI1 fundamentally working --- fw/main.c | 122 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 44 deletions(-) diff --git a/fw/main.c b/fw/main.c index 9470f5c..eb317e4 100644 --- a/fw/main.c +++ b/fw/main.c @@ -58,14 +58,6 @@ volatile uint8_t this_addr = 0x05; /* FIXME */ #define SR_ILED_HIGH 0x0080 #define SR_ILED_LOW 0x0040 -void shift_aux(int global_current, int leds, int active_segment) { - spi_send( - (global_current ? SR_ILED_HIGH : SR_ILED_LOW) - | (leds<<1) - | (0xff00 ^ (0x100<VAL; } @@ -74,6 +66,57 @@ inline unsigned int stk_end(unsigned int start) { return (start - SysTick->VAL) & 0xffffff; } +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; + SPI1->CR2 &= ~SPI_CR2_DS_Msk; + SPI1->CR2 &= ~SPI_CR2_DS_Msk; + SPI1->CR2 |= LL_SPI_DATAWIDTH_16BIT; + + /* Baud rate PCLK/2 -> 25MHz */ + SPI1->CR1 = + SPI_CR1_BIDIMODE + | SPI_CR1_BIDIOE + | SPI_CR1_SSM + | SPI_CR1_SSI + | SPI_CR1_SPE + | (0<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 ++; +} + static volatile int frame_duration; /* returns new bit time in cycles */ int shift_data() { @@ -82,6 +125,7 @@ int shift_data() { static int last_frame_sys_time; /* Note: On boot, multiplexing will start with bit 1 due to the next few lines. This is perfectly ok. */ + int rv = 1<brightness, led_state, active_segment); + 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; } + SPI1->CR2 |= SPI_CR2_TXEIE; - uint32_t current_word = read_fb->data[active_bit*frame_size_words + active_segment]; - spi_send(current_word&0xffff); - spi_send(current_word>>16); - strobe_leds(); - - if (current_word&0xffff) - asm("bkpt"); - - return 1<CCMR1 = 6<CCER = TIM_CCER_CC1E | TIM_CCER_CC1P; /* Inverting output */ - TIM3->DIER = TIM_DIER_CC1IE; - TIM3->CCR1 = 1000; /* Schedule first interrupt */ + TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P | TIM_CCER_CC2E | TIM_CCER_CC2P; /* Inverting output */ + TIM3->DIER = TIM_DIER_CC2IE; + TIM3->CCR2 = 1000; /* Schedule first interrupt */ TIM3->PSC = SystemCoreClock/5000000 * 2; /* 0.40us/tick */ TIM3->ARR = 0xffff; TIM3->EGR |= TIM_EGR_UG; @@ -129,16 +178,18 @@ void cfg_timer3() { NVIC_SetPriority(TIM3_IRQn, 2); } - void TIM3_IRQHandler() { //TIM3->CR1 &= ~TIM_CR1_CEN_Msk; FIXME - /* This takes about 10us */ int period = shift_data(); TIM3->CCR1 = period; - TIM3->CNT = 0xffff; /* To not enable OC1 right away */ + if (period < 32) /* FIXME this constant */ + TIM3->CCR2 = 32; + else + TIM3->CCR2 = period; + TIM3->CNT = 0xffff; /* To not enable OC1 riglt away */ - TIM3->SR &= ~TIM_SR_CC1IF_Msk; + TIM3->SR &= ~TIM_SR_CC2IF_Msk; //TIM3->CR1 |= TIM_CR1_CEN; } @@ -291,29 +342,12 @@ int main(void) { | (1<I2SCFGR = 0; - SPI1->CR2 &= ~SPI_CR2_DS_Msk; - SPI1->CR2 &= ~SPI_CR2_DS_Msk; - SPI1->CR2 |= LL_SPI_DATAWIDTH_16BIT; - - /* Baud rate PCLK/2 -> 25MHz */ - SPI1->CR1 = - SPI_CR1_BIDIMODE - | SPI_CR1_BIDIOE - | SPI_CR1_SSM - | SPI_CR1_SSI - | SPI_CR1_SPE - | (0<brightness = 1; for (int i=0; idata)/sizeof(uint32_t); i++) { - read_fb->data[i] = 0x00000000; + read_fb->data[i] = 0xffffffff; /* FIXME DEBUG 0x00000000; */ } cfg_timer3(); -- cgit