X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=dmx%2Ffirmware%2Fmain.c;h=47ff5d35e3cb7d34fa70e8c46552f2692626f997;hb=HEAD;hp=cc0b82625b26af5152df4a9e69b206b015449fc8;hpb=1179ee48d9d2d23d43df0d074fdd56609484810f;p=home-hw.git diff --git a/dmx/firmware/main.c b/dmx/firmware/main.c index cc0b826..47ff5d3 100644 --- a/dmx/firmware/main.c +++ b/dmx/firmware/main.c @@ -57,8 +57,12 @@ static void gpio_init(void) // PB10 = TXD3 for DMX // PB11 = RXD3 for DMX - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO10); + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO10); gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO11); + + // PB1 = TX enable for DMX (always on) + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO1); + gpio_set(GPIOB, GPIO1); } static void usart_init(void) @@ -98,11 +102,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 +131,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 +146,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 +202,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 +223,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 +368,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 +443,7 @@ int main(void) dmx_init(); u32 last_blink = 0; + u32 last_send = 0; for (;;) { if (ms_ticks - last_blink >= 100) { @@ -448,6 +459,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(); }