예제 #1
0
/**
  * @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;
}
예제 #2
0
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;
  }
}
예제 #3
0
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);
}
예제 #4
0
{
    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));