static void udi_cdc_tx_send(void) { irqflags_t flags; uint8_t buf_sel_trans; bool b_short_packet; if (udi_cdc_tx_trans_ongoing) { return; // Already on going or wait next SOF to send next data } if (udd_is_high_speed()) { if (udi_cdc_tx_sof_num == udd_get_micro_frame_number()) { return; // Wait next SOF to send next data } }else{ if (udi_cdc_tx_sof_num == udd_get_frame_number()) { return; // Wait next SOF to send next data } } flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel buf_sel_trans = udi_cdc_tx_buf_sel; if (!udi_cdc_tx_both_buf_to_send) { // Send current Buffer // and switch the current buffer udi_cdc_tx_buf_sel = (buf_sel_trans==0)?1:0; }else{ // Send the other Buffer // and no switch the current buffer buf_sel_trans = (buf_sel_trans==0)?1:0; } udi_cdc_tx_trans_ongoing = true; cpu_irq_restore(flags); b_short_packet = (udi_cdc_tx_buf_nb[buf_sel_trans] != UDI_CDC_TX_BUFFERS); if (b_short_packet) { if (udd_is_high_speed()) { udi_cdc_tx_sof_num = udd_get_micro_frame_number(); }else{ udi_cdc_tx_sof_num = udd_get_frame_number(); } }else{ udi_cdc_tx_sof_num = 0; // Force next transfer without wait SOF } // Send the buffer with enable of short packet udd_ep_run( UDI_CDC_DATA_EP_IN, b_short_packet, udi_cdc_tx_buf[buf_sel_trans], udi_cdc_tx_buf_nb[buf_sel_trans], udi_cdc_data_sent); }
static void udi_cdc_tx_send(uint8_t port) { irqflags_t flags; uint8_t buf_sel_trans; bool b_short_packet; udd_ep_id_t ep; static uint16_t sof_zlp_counter = 0; #if UDI_CDC_PORT_NB == 1 // To optimize code port = 0; #endif if (udi_cdc_tx_trans_ongoing[port]) { return; // Already on going or wait next SOF to send next data } if (udd_is_high_speed()) { if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { return; // Wait next SOF to send next data } }else{ if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { return; // Wait next SOF to send next data } } flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel buf_sel_trans = udi_cdc_tx_buf_sel[port]; if (udi_cdc_tx_buf_nb[port][buf_sel_trans] == 0) { sof_zlp_counter++; if (((!udd_is_high_speed()) && (sof_zlp_counter < 100)) || (udd_is_high_speed() && (sof_zlp_counter < 800))) { cpu_irq_restore(flags); return; } } sof_zlp_counter = 0; if (!udi_cdc_tx_both_buf_to_send[port]) { // Send current Buffer // and switch the current buffer udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; }else{ // Send the other Buffer // and no switch the current buffer buf_sel_trans = (buf_sel_trans==0)?1:0; } udi_cdc_tx_trans_ongoing[port] = true; cpu_irq_restore(flags); b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); if (b_short_packet) { if (udd_is_high_speed()) { udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); }else{ udi_cdc_tx_sof_num[port] = udd_get_frame_number(); } }else{ udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF } // Send the buffer with enable of short packet switch (port) { #define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ case index: \ ep = UDI_CDC_DATA_EP_IN_##index; \ break; MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) #undef UDI_CDC_PORT_TO_DATA_EP_IN default: ep = UDI_CDC_DATA_EP_IN_0; break; } udd_ep_run( ep, b_short_packet, udi_cdc_tx_buf[port][buf_sel_trans], udi_cdc_tx_buf_nb[port][buf_sel_trans], udi_cdc_data_sent); }