Implement DMX reciever and add more advanced failure mode #1
@@ -1,21 +1,34 @@
 | 
				
			|||||||
#include <ring-light/dmx.h>
 | 
					#include <ring-light/dmx.h>
 | 
				
			||||||
#include <stm32f0xx.h>
 | 
					#include <stm32f0xx.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static volatile bool dmx_new_data_avail = false;
 | 
					 | 
				
			||||||
static uint32_t dmx_base_channel;
 | 
					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)
 | 
					void dmx_init(uint32_t base_channel)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						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++) {
 | 
						for (i = 0, ptr = dmx_channel_data; i < DMX_USED_CHANNEL_COUNT; i++, ptr++) {
 | 
				
			||||||
		*ptr = 0u;
 | 
							*ptr = 0u;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dmx_base_channel = base_channel;
 | 
						dmx_base_channel = base_channel;
 | 
				
			||||||
 | 
						dmx_write_pointer = 0u;
 | 
				
			||||||
 | 
						dmx_rx_state = DMX_RX_WAIT_FOR_BREAK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Enable GPIOA and USART1 clock */
 | 
						/* Enable GPIOA and USART1 clock */
 | 
				
			||||||
	RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
 | 
						RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
 | 
				
			||||||
@@ -35,31 +48,52 @@ void dmx_init(uint32_t base_channel)
 | 
				
			|||||||
	USART1->CR2 = USART_CR2_STOP_1;
 | 
						USART1->CR2 = USART_CR2_STOP_1;
 | 
				
			||||||
	USART1->CR1 = USART_CR1_RXNEIE | USART_CR1_RE | USART_CR1_UE;
 | 
						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);
 | 
						NVIC_EnableIRQ(USART1_IRQn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool dmx_new_data_available()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return dmx_new_data_avail;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const uint8_t *dmx_get_data()
 | 
					const uint8_t *dmx_get_data()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return dmx_channel_data;
 | 
						return (const uint8_t *)&dmx_channel_data[1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void USART1_IRQHandler(void)
 | 
					void USART1_IRQHandler(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t isr;
 | 
						uint32_t isr;
 | 
				
			||||||
	volatile uint8_t dreg;
 | 
						uint8_t dreg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	isr = USART1->ISR;
 | 
						isr = USART1->ISR;
 | 
				
			||||||
	USART1->ICR = USART_ICR_ORECF | USART_ICR_NCF | USART_ICR_FECF;
 | 
						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;
 | 
							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();
 | 
						__DSB();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DMA_CH2_3_DMA2_CH1_2_IRQHandler()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,12 +28,6 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void dmx_init(uint32_t base_channel);
 | 
					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
 | 
					 * @brief Returns the array of the 129 DMX channels
 | 
				
			||||||
 * @return
 | 
					 * @return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,7 +96,7 @@ void DMA_CH1_IRQHandler(void)
 | 
				
			|||||||
	uint32_t isr;
 | 
						uint32_t isr;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	isr = DMA1->ISR;
 | 
						isr = DMA1->ISR;
 | 
				
			||||||
	DMA1->IFCR = isr;
 | 
						DMA1->IFCR = isr & 0xF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (isr & DMA_ISR_TCIF1) {
 | 
						if (isr & DMA_ISR_TCIF1) {
 | 
				
			||||||
		process_adc_samples();
 | 
							process_adc_samples();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user