From d0cdde2a4d3983780d4dd08e6970dccd1b37a073 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 11 Apr 2020 15:53:05 +0200 Subject: [PATCH] DMX: USB interface --- dmx/firmware/main.c | 50 +++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/dmx/firmware/main.c b/dmx/firmware/main.c index cc0b826..f2b89f7 100644 --- a/dmx/firmware/main.c +++ b/dmx/firmware/main.c @@ -98,11 +98,16 @@ static void delay_ms(uint ms) /*** DMX ***/ +#define DMX_MAX_PACKET_SIZE 64 + static volatile byte dmx_state; -static byte dmx_packet[64]; +static byte dmx_packet[DMX_MAX_PACKET_SIZE]; static byte dmx_pos, dmx_len; -#define DEBUG_DMX +static byte dmx_next_packet[DMX_MAX_PACKET_SIZE]; +static byte dmx_next_len; + +#undef DEBUG_DMX #ifdef DEBUG_DMX #define DMX_DEBUG(ch) debug_putc(ch) #else @@ -122,7 +127,7 @@ static void dmx_init(void) { usart_set_baudrate(USART3, 250000); usart_set_databits(USART3, 8); - usart_set_stopbits(USART3, USART_STOPBITS_1); + usart_set_stopbits(USART3, USART_STOPBITS_2); usart_set_mode(USART3, USART_MODE_TX); usart_set_parity(USART3, USART_PARITY_NONE); usart_set_flow_control(USART3, USART_FLOWCONTROL_NONE); @@ -137,6 +142,10 @@ static void dmx_init(void) timer_one_shot_mode(TIM3); timer_enable_irq(TIM3, TIM_DIER_UIE); nvic_enable_irq(NVIC_TIM3_IRQ); + + // Until we get data from USB, send "turn everything off" packets + memset(dmx_next_packet, 0, DMX_MAX_PACKET_SIZE); + dmx_next_len = DMX_MAX_PACKET_SIZE; } void tim3_isr(void) @@ -189,9 +198,9 @@ void usart3_isr(void) // Transfer of the last byte is complete, but we have to wait // before the start of the next packet: minimum time between two // breaks must be at least 1204 μs. We already sent a 200μs break, - // 200μs mark, and dmx_len 40μs data slots. + // 200μs mark, and dmx_len 44μs data slots. USART_CR1(USART3) &= ~USART_CR1_TCIE; - uint sent = 200 + 200 + 40*dmx_len; + uint sent = 200 + 200 + 44*dmx_len; if (sent < 1300) { DMX_DEBUG('g'); dmx_state = DMX_STATE_GAP; @@ -210,13 +219,10 @@ static void dmx_send(void) if (dmx_state != DMX_STATE_IDLE) return; - dmx_packet[0] = 0; - dmx_packet[1] = 0xff; // warm - dmx_packet[2] = 0xff; // cold - dmx_packet[3] = 0; - dmx_packet[4] = 0; + if (!dmx_len) + return; + dmx_pos = 0; - dmx_len = 5; // Send break for 200 μs DMX_DEBUG('<'); @@ -358,9 +364,9 @@ static enum usbd_request_return_codes dfu_control_cb(usbd_device *dev UNUSED, static void ep01_cb(usbd_device *dev, uint8_t ep UNUSED) { // We received a frame from the USB host - byte buf[64]; - uint len = usbd_ep_read_packet(dev, 0x01, buf, sizeof(buf)); + uint len = usbd_ep_read_packet(dev, 0x01, dmx_next_packet, DMX_MAX_PACKET_SIZE); debug_printf("USB: Host sent %u bytes\n", len); + dmx_next_len = len; } static void set_config_cb(usbd_device *dev, uint16_t wValue UNUSED) @@ -433,6 +439,7 @@ int main(void) dmx_init(); u32 last_blink = 0; + u32 last_send = 0; for (;;) { if (ms_ticks - last_blink >= 100) { @@ -448,6 +455,23 @@ int main(void) nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); } + if (dmx_state == DMX_STATE_IDLE) { + if (dmx_next_len) { + // We have a new packet to send + debug_printf("Sending new packet: %d bytes\n", dmx_next_len); + memcpy(dmx_packet, dmx_next_packet, dmx_next_len); + dmx_len = dmx_next_len; + dmx_next_len = 0; + dmx_send(); + last_send = ms_ticks; + } else if (ms_ticks - last_send >= 100) { + // Re-send every 100 ms + // debug_printf("Re-send: %d bytes\n", dmx_len); + dmx_send(); + last_send = ms_ticks; + } + } + wait_for_interrupt(); } -- 2.39.2