diff --git a/firmware/dmx.c b/firmware/dmx.c index 63c1868..5986a57 100644 --- a/firmware/dmx.c +++ b/firmware/dmx.c @@ -1,21 +1,34 @@ #include #include -static volatile bool dmx_new_data_avail = false; static uint32_t dmx_base_channel; -static uint8_t dmx_channel_data[DMX_USED_CHANNEL_COUNT]; + +enum dmx_rx_state_enum { + DMX_RX_WAIT_FOR_BREAK = 0, + DMX_RX_DATA, +}; + +/** + * @brief DMX data received. Contains the whole DMX universe including the first 0 byte. + * The controller does check the first byte to be zero. + */ +static volatile uint8_t dmx_channel_data[DMX_UNIVERSE_SIZE + 1]; + +static volatile enum dmx_rx_state_enum dmx_rx_state; +static volatile uint32_t dmx_write_pointer; void dmx_init(uint32_t base_channel) { int i; - uint8_t *ptr; + volatile uint8_t *ptr; - dmx_new_data_avail = false; for (i = 0, ptr = dmx_channel_data; i < DMX_USED_CHANNEL_COUNT; i++, ptr++) { *ptr = 0u; } dmx_base_channel = base_channel; + dmx_write_pointer = 0u; + dmx_rx_state = DMX_RX_WAIT_FOR_BREAK; /* Enable GPIOA and USART1 clock */ RCC->AHBENR |= RCC_AHBENR_GPIOAEN; @@ -35,31 +48,52 @@ void dmx_init(uint32_t base_channel) USART1->CR2 = USART_CR2_STOP_1; USART1->CR1 = USART_CR1_RXNEIE | USART_CR1_RE | USART_CR1_UE; + /* Map USART1 RX to DMA Channel 3 */ + SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_USART1RX_DMA_RMP; + NVIC_EnableIRQ(USART1_IRQn); } -bool dmx_new_data_available() -{ - return dmx_new_data_avail; -} const uint8_t *dmx_get_data() { - return dmx_channel_data; + return (const uint8_t *)&dmx_channel_data[1]; } void USART1_IRQHandler(void) { uint32_t isr; - volatile uint8_t dreg; + uint8_t dreg; isr = USART1->ISR; USART1->ICR = USART_ICR_ORECF | USART_ICR_NCF | USART_ICR_FECF; - if (isr & USART_ISR_RXNE) { + if (isr & USART_ISR_FE) { + /* Frame error received. Start of DMX frame */ + dmx_write_pointer = 0u; + dmx_rx_state = DMX_RX_DATA; + /* Flush RX data */ + USART1->RQR = USART_RQR_RXFRQ; + } else if (isr & USART_ISR_RXNE) { + /* Received valid symbol */ dreg = (uint8_t)USART1->RDR; - dmx_channel_data[0] = dreg; + + if (dmx_rx_state == DMX_RX_DATA) { + /* Ready to recieve data */ + if (dmx_write_pointer < (DMX_UNIVERSE_SIZE + 1)) { + dmx_channel_data[dmx_write_pointer] = dreg; + dmx_write_pointer++; + } else { + dmx_rx_state = DMX_RX_WAIT_FOR_BREAK; + } + } + } __DSB(); } + +void DMA_CH2_3_DMA2_CH1_2_IRQHandler() +{ + +} diff --git a/firmware/include/ring-light/dmx.h b/firmware/include/ring-light/dmx.h index 2c35889..748f11b 100644 --- a/firmware/include/ring-light/dmx.h +++ b/firmware/include/ring-light/dmx.h @@ -28,12 +28,6 @@ */ void dmx_init(uint32_t base_channel); -/** - * @brief Has new DMX data been received? - * @return true if new data is available - */ -bool dmx_new_data_available(void); - /** * @brief Returns the array of the 129 DMX channels * @return diff --git a/firmware/temp-adc.c b/firmware/temp-adc.c index a488a55..d3c019c 100644 --- a/firmware/temp-adc.c +++ b/firmware/temp-adc.c @@ -96,7 +96,7 @@ void DMA_CH1_IRQHandler(void) uint32_t isr; isr = DMA1->ISR; - DMA1->IFCR = isr; + DMA1->IFCR = isr & 0xF; if (isr & DMA_ISR_TCIF1) { process_adc_samples();