Implement test RX for DMX. Still no functionality

This commit is contained in:
Mario Hüttel 2022-06-24 18:08:28 +02:00
parent 3faab7173c
commit d06b2b7eaf
3 changed files with 47 additions and 19 deletions

View File

@ -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()
{
}

View File

@ -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

View File

@ -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();