void main_cdc_rx_notify(uint8_t port){ // Byte received on USB on port in argument ui_com_rx_notify(port); switch(port){ case 0: // send directly to serial port while(udi_cdc_multi_is_rx_ready(port)){ int c = udi_cdc_multi_getc(port); if(!lithneProgrammer.busyProgramming()){ // don't send anything to the serial port when the programmer is busy usart_putchar(&USART_COMM0, c); } } break; case 1: while(udi_cdc_multi_is_rx_ready(port)){ int c = udi_cdc_multi_getc(port); usart_putchar(&USART_XBEE, c); } break; default: return; // unknown port, do nothing } }
static bool udi_cdc_rx_start(uint8_t port) { irqflags_t flags; uint8_t buf_sel_trans; udd_ep_id_t ep; #if UDI_CDC_PORT_NB == 1 // To optimize code port = 0; #endif flags = cpu_irq_save(); buf_sel_trans = udi_cdc_rx_buf_sel[port]; if (udi_cdc_rx_trans_ongoing[port] || (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { // Transfer already on-going or current buffer no empty cpu_irq_restore(flags); return false; } // Change current buffer udi_cdc_rx_pos[port] = 0; udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; // Start transfer on RX udi_cdc_rx_trans_ongoing[port] = true; cpu_irq_restore(flags); if (udi_cdc_multi_is_rx_ready(port)) { UDI_CDC_RX_NOTIFY(port); } // Send the buffer with enable of short packet switch (port) { #define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ case index: \ ep = UDI_CDC_DATA_EP_OUT_##index; \ break; MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) #undef UDI_CDC_PORT_TO_DATA_EP_OUT default: ep = UDI_CDC_DATA_EP_OUT_0; break; } return udd_ep_run(ep, true, udi_cdc_rx_buf[port][buf_sel_trans], UDI_CDC_RX_BUFFERS, udi_cdc_data_received); }
/*! \brief Main function. Execution starts here. */ int main(void) { irq_initialize_vectors(); cpu_irq_enable(); // Initialize the sleep manager sleepmgr_init(); sysclk_init(); board_init(); ui_init(); ui_powerdown(); // Start USB stack to authorize VBus monitoring udc_start(); // The main loop manages only the power mode // because the USB management is done by interrupt while (true) { sleepmgr_enter_sleep(); if (main_b_cdc_enable) { // Here CPU wakeup at each SOF (1ms) for (uint8_t port = 0; port < UDI_CDC_PORT_NB; port++) { if (!(main_port_open & (1 << port))) { // Port not open continue; } if (!udi_cdc_multi_is_rx_ready(port)) { // No data received continue; } int value = udi_cdc_multi_getc(port); if (value != 'p') { // Ignore this value continue; } udi_cdc_multi_write_buf(port, "PORT", sizeof("PORT")-1); udi_cdc_multi_putc(port, port+'0'); udi_cdc_multi_putc(port, '\n'); udi_cdc_multi_putc(port, '\r'); } } } }
static void usart_handler(uint8_t port) { Usart* usart = get_usart(port); uint32_t sr = usart_get_status(usart); if (sr & US_CSR_RXRDY) { // Data received ui_com_tx_start(); uint32_t value; bool b_error = usart_read(usart, &value) || (sr & (US_CSR_FRAME | US_CSR_TIMEOUT | US_CSR_PARE)); if (b_error) { usart_reset_rx(usart); usart_enable_rx(usart); udi_cdc_multi_signal_framing_error(port); ui_com_error(); } // Transfer UART RX fifo to CDC TX if (!udi_cdc_multi_is_tx_ready(port)) { // Fifo full udi_cdc_multi_signal_overrun(port); ui_com_overflow(); } else { udi_cdc_multi_putc(port, value); } ui_com_tx_stop(); return; } if (sr & US_CSR_TXRDY) { // Data send if (udi_cdc_multi_is_rx_ready(port)) { // Transmit next data ui_com_rx_start(); int c = udi_cdc_multi_getc(port); usart_write(usart, c); } else { // Fifo empty then Stop UART transmission usart_disable_tx(usart); usart_disable_interrupt(usart, US_IDR_TXRDY); ui_com_rx_stop(); } } }
static bool udi_cdc_rx_start(uint8_t port) { irqflags_t flags; uint8_t buf_sel_trans; flags = cpu_irq_save(); buf_sel_trans = udi_cdc_rx_buf_sel[PORT]; if (udi_cdc_rx_trans_ongoing[PORT] || (udi_cdc_rx_pos[PORT] < udi_cdc_rx_buf_nb[PORT][buf_sel_trans])) { // Transfer already on-going or current buffer no empty cpu_irq_restore(flags); return false; } // Change current buffer udi_cdc_rx_pos[PORT] = 0; udi_cdc_rx_buf_sel[PORT] = (buf_sel_trans==0)?1:0; // Start transfer on RX udi_cdc_rx_trans_ongoing[PORT] = true; cpu_irq_restore(flags); if (udi_cdc_multi_is_rx_ready(PORT)) { #if UDI_CDC_PORT_NB == 1 UDI_CDC_RX_NOTIFY(); #else UDI_CDC_RX_NOTIFY(port); #endif } return udd_ep_run( UDI_CDC_DATA_EP_OUTS[PORT], true, udi_cdc_rx_buf[PORT][buf_sel_trans], UDI_CDC_RX_BUFFERS, udi_cdc_data_received_callbacks[PORT]); }
bool udi_cdc_is_rx_ready(void) { return udi_cdc_multi_is_rx_ready(0); }