/** * @brief usbd_audio_DataIn * Data sent on non-control IN endpoint * @param pdev: device instance * @param epnum: endpoint number * @retval status */ static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) { uint32_t USB_Tx_length; usbd_cdc_Change_Open_State(1); if (!USB_Tx_State) return USBD_OK; USB_Tx_length = ring_data_contig(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_head, USB_Tx_Buffer_tail); if (USB_Tx_length) { USB_Tx_length = MIN(USB_Tx_length, CDC_DATA_IN_PACKET_SIZE); } else if (usbd_Last_Tx_Packet_size(pdev, epnum) != CDC_DATA_IN_PACKET_SIZE) { USB_Tx_State = 0; return USBD_OK; } /* Prepare the available data buffer to be sent on IN endpoint */ DCD_EP_Tx (pdev, CDC_IN_EP, (uint8_t*)&USB_Tx_Buffer[USB_Tx_Buffer_tail], USB_Tx_length); USB_Tx_Buffer_tail = ring_wrap(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_tail + USB_Tx_length); return USBD_OK; }
static inline void usbd_cdc_Change_Open_State(uint8_t state) { if (state != USB_Serial_Open) { DEBUG("USB Serial state: %d", state); if (state) { USB_Tx_failed_counter = 0; // Also flush everything in TX buffer uint32_t USB_Tx_length; USB_Tx_length = ring_data_contig(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_head, USB_Tx_Buffer_tail); if (USB_Tx_length) USB_Tx_Buffer_tail = ring_wrap(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_tail + USB_Tx_length); USB_Tx_State = 0; USB_Rx_State = 1; } USB_Serial_Open = state; } }
static void usbd_cdc_Schedule_In(void *pdev) { uint32_t USB_Tx_length; USB_Tx_length = ring_data_contig(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_head, USB_Tx_Buffer_tail); if (USB_Tx_State) { if (USB_Serial_Open) { USB_Tx_failed_counter++; if (USB_Tx_failed_counter >= 500) { usbd_cdc_Change_Open_State(0); // Completely flush TX buffer DCD_EP_Flush(pdev, CDC_IN_EP); // Send ZLP DCD_EP_Tx(pdev, CDC_IN_EP, NULL, 0); if (USB_Tx_length) USB_Tx_Buffer_tail = ring_wrap(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_tail + USB_Tx_length); USB_Tx_State = 0; } } return; } if (!USB_Tx_length) return; USB_Tx_State = 1; USB_Tx_failed_counter = 0; USB_Tx_length = MIN(USB_Tx_length, CDC_DATA_IN_PACKET_SIZE); DCD_EP_Tx (pdev, CDC_IN_EP, (uint8_t*)&USB_Tx_Buffer[USB_Tx_Buffer_tail], USB_Tx_length); USB_Tx_Buffer_tail = ring_wrap(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_tail + USB_Tx_length); }
{ while (serial.available() > 0) { (void)serial.read(); } } test(0_USBSERIAL_RingBufferHelperIsSane) { uint32_t size = 129; uint32_t head = 0; uint32_t tail = 0; head = 0; tail = 0; assertEqual(0, ring_data_avail(size, head, tail)); assertEqual(128, ring_space_avail(size, head, tail)); assertEqual(0, ring_data_contig(size, head, tail)); assertEqual(128, ring_space_contig(size, head, tail)); assertEqual(0, ring_space_wrapped(size, head, tail)); head = 63; tail = 0; assertEqual(63, ring_data_avail(size, head, tail)); assertEqual(65, ring_space_avail(size, head, tail)); assertEqual(63, ring_data_contig(size, head, tail)); assertEqual(65, ring_space_contig(size, head, tail)); assertEqual(0, ring_space_wrapped(size, head, tail)); head = 63; tail = 32; assertEqual(31, ring_data_avail(size, head, tail)); assertEqual(97, ring_space_avail(size, head, tail));