int udi_cdc_multi_putc(uint8_t port, int value) { irqflags_t flags; bool b_databit_9; uint8_t buf_sel; #if UDI_CDC_PORT_NB == 1 // To optimize code port = 0; #endif b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); udi_cdc_putc_process_one_byte: // Check available space if (!udi_cdc_multi_is_tx_ready(port)) { if (!udi_cdc_data_running) { return false; } goto udi_cdc_putc_process_one_byte; } // Write value flags = cpu_irq_save(); buf_sel = udi_cdc_tx_buf_sel[port]; udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; cpu_irq_restore(flags); if (b_databit_9) { // Send MSB b_databit_9 = false; value = value >> 8; goto udi_cdc_putc_process_one_byte; } return true; }
int udi_cdc_multi_putc(uint8_t port, int value) { irqflags_t flags; bool b_databit_9; uint8_t buf_sel; b_databit_9 = (9 == udi_cdc_line_coding[PORT].bDataBits); udi_cdc_putc_process_one_byte: // Check avaliable space if (!udi_cdc_multi_is_tx_ready(PORT)) { if (!udi_cdc_running[PORT]) { return false; } goto udi_cdc_putc_process_one_byte; } // Write value flags = cpu_irq_save(); buf_sel = udi_cdc_tx_buf_sel[PORT]; udi_cdc_tx_buf[PORT][buf_sel][udi_cdc_tx_buf_nb[PORT][buf_sel]++] = value; cpu_irq_restore(flags); if (b_databit_9) { // Send MSB b_databit_9 = false; value = value >> 8; goto udi_cdc_putc_process_one_byte; } return true; }
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) { irqflags_t flags; uint8_t buf_sel; uint16_t buf_nb; iram_size_t copy_nb; uint8_t *ptr_buf = (uint8_t *)buf; #if UDI_CDC_PORT_NB == 1 // To optimize code port = 0; #endif if (9 == udi_cdc_line_coding[port].bDataBits) { size *=2; } hashfast_init_udi_cdc_write_timeout(); udi_cdc_write_buf_loop_wait: // Check available space if (!udi_cdc_multi_is_tx_ready(port)) { if (!udi_cdc_data_running) { return size; } if (hashfast_udi_cdc_timeout()) return size; goto udi_cdc_write_buf_loop_wait; } // Write values flags = cpu_irq_save(); buf_sel = udi_cdc_tx_buf_sel[port]; buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; if (copy_nb > size) { copy_nb = size; } memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; cpu_irq_restore(flags); // Update buffer pointer ptr_buf = ptr_buf + copy_nb; size -= copy_nb; if (size) { if (hashfast_udi_cdc_timeout()) return(size); goto udi_cdc_write_buf_loop_wait; } return 0; }
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(); } } }
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const int* buf, iram_size_t size) { irqflags_t flags; uint8_t buf_sel; uint16_t buf_nb; iram_size_t copy_nb; uint8_t *ptr_buf = (uint8_t *)buf; if (9 == udi_cdc_line_coding[PORT].bDataBits) { size *=2; } udi_cdc_write_buf_loop_wait: // Check avaliable space if (!udi_cdc_multi_is_tx_ready(PORT)) { if (!udi_cdc_running[PORT]) { return size; } goto udi_cdc_write_buf_loop_wait; } // Write values flags = cpu_irq_save(); buf_sel = udi_cdc_tx_buf_sel[PORT]; buf_nb = udi_cdc_tx_buf_nb[PORT][buf_sel]; copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; if (copy_nb>size) { copy_nb = size; } memcpy(&udi_cdc_tx_buf[PORT][buf_sel][buf_nb], ptr_buf, copy_nb); udi_cdc_tx_buf_nb[PORT][buf_sel] = buf_nb + copy_nb; cpu_irq_restore(flags); // Update buffer pointer ptr_buf = ptr_buf + copy_nb; size -= copy_nb; if (size) { goto udi_cdc_write_buf_loop_wait; } return 0; }
bool udi_cdc_is_tx_ready(void) { return udi_cdc_multi_is_tx_ready(0); }