| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -1,21 +1,34 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <ring-light/dmx.h>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <stm32f0xx.h>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				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()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					
					| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				 
 |