/*** 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
{
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);
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)
// 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;
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('<');
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)
dmx_init();
u32 last_blink = 0;
+ u32 last_send = 0;
for (;;) {
if (ms_ticks - last_blink >= 100) {
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();
}