コード例 #1
0
ファイル: usbSerializer.c プロジェクト: femtoio/femto-beacon
/******************************************************************************
Causes the given endpoint to acknowledge the next packet it receives with
a STALL handshake.
******************************************************************************/
void stallData(void)
{
  if (UDP_ENDPOINT_IDLE != epState)
    return;

  setCSR(UDP_CSR_FORCESTALL);
}
コード例 #2
0
ファイル: usbSerializer.c プロジェクト: femtoio/femto-beacon
/******************************************************************************
Sends data through a USB endpoint.

Parameters:
  data - Pointer to a buffer with the data to send.
  size - Size of the data buffer.
  callback - Optional callback function to invoke when the transfer is complete.
  argument - Optional argument to the callback function.
******************************************************************************/
void txUsbData(void *data, uint32_t size, TransferCallback_t callback, void *argument)
{
  // Setup the transfer descriptor
  transfer.data = (void *) data;
  transfer.remaining = size;
  transfer.buffered = 0;
  transfer.transferred = 0;
  transfer.callback = callback;
  transfer.argument = argument;

  // Send the first packet
  epState = UDP_ENDPOINT_SENDING;
  while (UDP_CSR_TXPKTRDY == (UDP->UDP_CSR[EP_NUMBER] & UDP_CSR_TXPKTRDY));
  writePayload();
  setCSR(UDP_CSR_TXPKTRDY);
}
コード例 #3
0
ファイル: usbSerializer.c プロジェクト: femtoio/femto-beacon
/**************************************************************************//**
\brief Startup initialization of the usb.
******************************************************************************/
void hwInitUsbDfu(void)
{
  // enables main clock on UDP for master clock domain
  PMC->PMC_PCER1 = (1ul << (ID_UDP - START_ID_NUMBER_FOR_PMC1));
  // enables 48 MHz clock on UDP phy for 12 MHz domain
  PMC->PMC_SCER = PMC_SCER_UDP;
  // Clear interrupt
  UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXSUSP | UDP_ICR_RXRSM;
  // enables UDP transceiver
  UDP->UDP_TXVC &= ~UDP_TXVC_TXVDIS;
  UDP->UDP_TXVC |= UDP_TXVC_PUON;
  // wait for usb bus reset
  while (!(UDP->UDP_ISR & UDP_ISR_ENDBUSRES));
  // Acknowledge end of bus reset interrupt and the others
  UDP->UDP_ICR = UDP_ISR_ENDBUSRES | UDP_ISR_WAKEUP | UDP_ISR_RXRSM | UDP_ISR_RXSUSP;
  // Reset Endpoint 0 Fifos
  UDP->UDP_RST_EP |= UDP_RST_EP_EP0;
  UDP->UDP_RST_EP &= ~UDP_RST_EP_EP0;
  // Configure endpoint 0
  setCSR(UDP_CSR_EPEDS | UDP_CSR_EPTYPE_CTRL | EP_OUT);
  // enumeration
  while (!(UDP->UDP_GLB_STAT & UDP_GLB_STAT_CONFG))
    epHandler();
}
コード例 #4
0
ファイル: usbSerializer.c プロジェクト: femtoio/femto-beacon
/**************************************************************************//**
\brief End point handler.
******************************************************************************/
static void epHandler(void)
{
  uint16_t i;
  uint8_t *ptr;

  // wait for transaction on 0 endpoint
  while (!(UDP->UDP_ISR & UDP_ISR_EP0INT));
  // acknowledge end point 0 interrupt
  UDP->UDP_ICR = UDP_ISR_EP0INT;

  epStatus = UDP->UDP_CSR[EP_NUMBER];
  // Handle endpoint actions
  // IN packet sent
  if (epStatus & UDP_CSR_TXCOMP)
  {
    // Check that endpoint was in Sending state
    if (UDP_ENDPOINT_SENDING == epState)
    {
      if (transfer.buffered < END_POINT_MAX_SIZE)
      { // transfer is finished
        transfer.transferred += transfer.buffered;
        transfer.buffered = 0;

        clearCSR(UDP_CSR_TXCOMP);
        // Endpoint returns in Idle state
        epState = UDP_ENDPOINT_IDLE;
        endOfTransfer();
      }
      else
      {
        // Transfer remaining data
        transfer.transferred += END_POINT_MAX_SIZE;
        transfer.buffered -= END_POINT_MAX_SIZE;
        // Send next packet
        writePayload();
        setCSR(UDP_CSR_TXPKTRDY);
        clearCSR(UDP_CSR_TXCOMP);
      }
    }
    else
    {
      // Acknowledge transaction
      clearCSR(UDP_CSR_TXCOMP);
    }
  }

  // OUT packet received
  if (epStatus & UDP_RXDATA)
  {
    // Check that the endpoint is in Receiving state
    if (UDP_ENDPOINT_RECEIVING != epState)
    {
      // Check if an ACK has been received on a Control endpoint
      if ((epStatus & UDP_CSR_RXBYTECNT) == 0)
      {
        // Acknowledge the data and finish the current transfer
        // Notify USB peripheral device that data have been read in the FIFO's Bank 0.
        UDP->UDP_CSR[EP_NUMBER] &= ~UDP_CSR_RX_DATA_BK0;
        while ((UDP->UDP_CSR[EP_NUMBER] & UDP_CSR_RX_DATA_BK0) == UDP_CSR_RX_DATA_BK0);
        // Endpoint returns in Idle state
        epState = UDP_ENDPOINT_IDLE;
        endOfTransfer();
      }
      // Check if the data has been STALLed
      else if (epStatus & UDP_CSR_FORCESTALL)
      {
        // Discard STALLed data
        // Notify USB peripheral device that data have been read in the FIFO's Bank 0.
        UDP->UDP_CSR[EP_NUMBER] &= ~UDP_CSR_RX_DATA_BK0;
        while ((UDP->UDP_CSR[EP_NUMBER] & UDP_CSR_RX_DATA_BK0) == UDP_CSR_RX_DATA_BK0);
      }
    }
    // Endpoint is in Read state
    else
    {
      // Retrieve data and store it into the current transfer buffer
      uint16_t size = (uint16_t)(epStatus >> 16);

      readPayload(size);
      // Notify USB peripheral device that data have been read in the FIFO's Bank 0.
      UDP->UDP_CSR[EP_NUMBER] &= ~UDP_CSR_RX_DATA_BK0;
      while ((UDP->UDP_CSR[EP_NUMBER] & UDP_CSR_RX_DATA_BK0) == UDP_CSR_RX_DATA_BK0);
      // Check if the transfer is finished
      if ((transfer.remaining == 0) || (size < END_POINT_MAX_SIZE))
      {
        // Endpoint returns in Idle state
        epState = UDP_ENDPOINT_IDLE;
        endOfTransfer();
      }
    }
  }

  // SETUP packet received
  if (epStatus & UDP_CSR_RXSETUP)
  {
    // If a transfer was pending, complete it
    // Handles the case where during the status phase of a control write
    // transfer, the host receives the device ZLP and ack it, but the ack
    // is not received by the device
    if ((UDP_ENDPOINT_RECEIVING == epState) || (UDP_ENDPOINT_SENDING == epState))
    {
      // Endpoint returns in Idle state
      epState = UDP_ENDPOINT_IDLE;
      endOfTransfer();
    }
    // Copy packet
    ptr = (uint8_t *)&request;
    for (i = 0; i < (uint16_t)(epStatus >> 16); i++)
    {
      *ptr = (uint8_t)UDP->UDP_FDR[EP_NUMBER];
      ptr++;
    }
    // Set the DIR bit before clearing RXSETUP in Control IN sequence
    // Transfer direction is located in bit D7 of the bmRequestType field
    if (request.bmRequestType & 0x80)
      setCSR(UDP_CSR_DIR);
    clearCSR(UDP_CSR_RXSETUP);
    // Forward the request to the upper layer
    runtimeRequestHandler();
  }

  // STALL sent
  if (epStatus & UDP_CSR_STALLSENTISOERROR)
  {
    // If the endpoint is not halted, clear the STALL condition
    clearCSR(UDP_CSR_STALLSENTISOERROR);
    clearCSR(UDP_CSR_FORCESTALL);
  }
}
コード例 #5
0
ファイル: processor.c プロジェクト: sam-falvo/kestrel
static void
andCSR(Processor *p, int csr, DWORD v) {
    setCSR(p, csr, v & getCSR(p, csr));
}
コード例 #6
0
ファイル: processor.c プロジェクト: sam-falvo/kestrel
static void
orCSR(Processor *p, int csr, DWORD v) {
    setCSR(p, csr, v | getCSR(p, csr));
}