Exemplo n.º 1
0
/**
 * Sets the active setting of the given interface if the configuration supports
 * it; otherwise, the control pipe is STALLed. If the setting of an interface
 * changes.
 * \parma pDriver  Pointer to a USBDDriver instance.
 * \parma infnum  Interface number.
 * \parma setting  New active setting for the interface.
 */
static void SetInterface(
    USBDDriver *pDriver,
    uint8_t infnum,
    uint8_t setting)
{
    /* Make sure alternate settings are supported */

    if (!pDriver->pInterfaces) {

        USBD_Stall(0);
    }
    else {

        /* Change the current setting of the interface and trigger the callback */
        /* if necessary */
        if (pDriver->pInterfaces[infnum] != setting) {

            pDriver->pInterfaces[infnum] = setting;
            USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting);
        }

        /* Acknowledge the request */

        USBD_Write(0, 0, 0, 0, 0);
    }
}
Exemplo n.º 2
0
/**************************************************************************//**
 * @brief
 *   Start a USB bulk-in transfer to send a CSW back to host.
 *****************************************************************************/
__STATIC_INLINE void SendCsw(void)
{
  if ( ledPort != -1 )
    GPIO_PinOutToggle((GPIO_Port_TypeDef)ledPort, ledPin);

  USBD_Write(BULK_IN, (void*) &csw, CSW_LEN, NULL);
}
Exemplo n.º 3
0
//------------------------------------------------------------------------------
/// Sends the current status of the device to the host.
/// \param pDriver  Pointer to a USBDDriver instance.
//------------------------------------------------------------------------------
static void GetDeviceStatus(const USBDDriver *pDriver)
{
    static unsigned short data;
    const USBConfigurationDescriptor *pConfiguration;

    data = 0;
    // Use different configuration depending on device speed
    if (USBD_IsHighSpeed()) {

        pConfiguration = pDriver->pDescriptors->pHsConfiguration;
    }
    else {

        pConfiguration = pDriver->pDescriptors->pFsConfiguration;
    }

    // Check current configuration for power mode (if device is configured)
    if (pDriver->cfgnum != 0) {

        if (USBConfigurationDescriptor_IsSelfPowered(pConfiguration)) {

            data |= 1;
        }
    }

    // Check if remote wake-up is enabled
    if (pDriver->isRemoteWakeUpEnabled) {

        data |= 2;
    }

    // Send the device status
    USBD_Write(0, &data, 2, 0, 0);
}
Exemplo n.º 4
0
inline uint16_t usb_send(const void *data, const uint16_t length) {
	if((send_status & (USB_IN_FUNCTION))) {
		return 0;
	}

	if(!(send_status & USB_CALLBACK)) {
		send_status |= USB_IN_FUNCTION;
		if(USBD_Write(IN_EP, data, length, usb_send_callback, 0) != USBD_STATUS_SUCCESS) {
			send_status &= ~USB_IN_FUNCTION;
			return 0;
		}
	} else {
		return 0;
	}

	uint16_t num_tries = 0;
	while(~send_status & USB_CALLBACK) {
		taskYIELD();
		num_tries++;
		// USBD_Write does not always call callback when USBD_STATUS_SUCCESS
		// Wait for NUM_SEND_TRIES
		if(num_tries > NUM_SEND_TRIES) {
			send_status = 0;
			return 0;
		}
	}

	send_status = 0;

	return usb_send_transferred;
}
Exemplo n.º 5
0
//------------------------------------------------------------------------------
/// Configures the device by setting it into the Configured state and
/// initializing all endpoints.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param cfgnum  Configuration number to set.
//------------------------------------------------------------------------------
static void SetConfiguration(USBDDriver *pDriver, unsigned char cfgnum)
{
    USBEndpointDescriptor *pEndpoints[BOARD_USB_NUMENDPOINTS+1];
    const USBConfigurationDescriptor *pConfiguration;

	pConfiguration = pDriver->pDescriptors->pFsConfiguration;

    // Set & save the desired configuration
    USBD_SetConfiguration(cfgnum);
    pDriver->cfgnum = cfgnum;

    // If the configuration is not 0, configure endpoints
    if (cfgnum != 0) {
    
        // Parse configuration to get endpoint descriptors
        USBConfigurationDescriptor_Parse(pConfiguration, 0, pEndpoints, 0);
    
        // Configure endpoints
        int i = 0;
        while (pEndpoints[i] != 0) {
    
            USBD_ConfigureEndpoint(pEndpoints[i]);
            i++;
        }
    }
    // Should be done before send the ZLP
    USBDDriverCallbacks_ConfigurationChanged(cfgnum);

    // Acknowledge the request
    USBD_Write(0, // Endpoint #0
               0, // No data buffer
               0, // No data buffer
               (TransferCallback) 0,
               (void *)  0);
}
Exemplo n.º 6
0
/**********************************************************
 * Interrupt handler for push button 1
 **********************************************************/
void GPIO_EVEN_IRQHandler(void)
{
  /* Clear the interrupt flag */
  GPIO->IFC = 1 << 10;
  
  /* Send message */
  USBD_Write(EP_IN, button1message, sizeof(button1message), dataSentCallback);
}
Exemplo n.º 7
0
/**
  Write data to a USB host.
  @param buffer The data to send.
  @param length How many bytes to send.
  @return The number of bytes successfully written.
  
  \b Example
  \code
  UsbSerial* usb = UsbSerial::get(); // get a reference to the usb system
  int written = usb->write( "hi hi", 5 );
  \endcode
*/
int UsbSerial::write( const char *buffer, int length )
{
  int rv = 0;
  if( USBD_GetState() == USBD_STATE_CONFIGURED ) {
    if( USBD_Write(CDCDSerialDriverDescriptors_DATAIN, buffer, length, 0, 0) == USBD_STATUS_SUCCESS )
      rv = length;
  }
  return rv;
}
Exemplo n.º 8
0
/**
 * Callback function when SetReport request data received from host
 * \param pArg Pointer to additional argument struct
 * \param status Result status
 * \param transferred Number of bytes transferred
 * \param remaining Number of bytes that are not transferred yet
 */
static void HIDDTransferDriver_ReportReceived(void *pArg,
                                              uint8_t status,
                                              uint32_t transferred,
                                              uint32_t remaining)
{
    HIDDTransferDriver *pDrv = &hiddTransferDriver;
    pDrv->iReportLen = transferred;
    USBD_Write(0, 0, 0, 0, 0);
}
Exemplo n.º 9
0
static void fastsource_get_feat_cur_val(uint8_t entity, uint8_t channel,
				   uint8_t control, uint8_t length)
{
	TRACE_INFO("get_feat(E%u, CN%u, CS%u, L%u) ", entity, channel, control, length);
	if (channel == 0 && control == AUDFeatureUnitDescriptor_MUTE && length == 1)
		USBD_Write(0, &usb_state.muted, sizeof(usb_state.muted), 0, 0);
	else
		USBD_Stall(0);
}
Exemplo n.º 10
0
static int firmware_get(const USB_Setup_TypeDef *setup)
{
    int res = USB_STATUS_REQ_ERR;

    CHECK_SETUP_IN(USBTHING_FIRMWARE_MAX_SIZE);

    res = USBD_Write(0, firmware_version, sizeof(firmware_version), NULL);

    return res;
}
Exemplo n.º 11
0
//------------------------------------------------------------------------------
/// Sends the current line coding information to the host through Control
/// endpoint 0.
//------------------------------------------------------------------------------
static void CDCDSerialDriver_GetLineCoding(void)
{
    TRACE_INFO_WP("gLineCoding ");

    USBD_Write(0,
               (void *) &(cdcdSerialDriver.lineCoding),
               sizeof(CDCLineCoding),
               0,
               0);
}
Exemplo n.º 12
0
/**
 * Sends the current line coding information to the host through Control
 * endpoint 0.
 * \param pCdcd Pointer to CDCDSerialPort instance.
 */
static void _GetLineCoding(CDCDSerialPort * pCdcd)
{
    TRACE_INFO_WP("gLineCoding ");

    USBD_Write(0,
               (void *) &(pCdcd->lineCoding),
               sizeof(CDCLineCoding),
               0,
               0);
}
Exemplo n.º 13
0
//------------------------------------------------------------------------------
/// Sends a data buffer through the virtual COM port created by the CDC
/// device serial driver. This function behaves exactly like USBD_Write.
/// \param data Pointer to the data buffer to send.
/// \param size Size of the data buffer in bytes.
/// \param callback Optional callback function to invoke when the transfer
///                 finishes.
/// \param argument Optional argument to the callback function.
/// \return USBD_STATUS_SUCCESS if the read operation has been started normally;
///         otherwise, the corresponding error code.
//------------------------------------------------------------------------------
unsigned char CDCDSerialDriver_Write(void *data,
                                     unsigned int size,
                                     TransferCallback callback,
                                     void *argument)
{
    return USBD_Write(CDCDSerialDriverDescriptors_DATAIN,
                      data,
                      size,
                      callback,
                      argument);
}
Exemplo n.º 14
0
/**
 * Sends the current configuration number to the host.
 * \param pDriver  Pointer to a USBDDriver instance.
 */
static void GetConfiguration(const USBDDriver *pDriver)
{
    unsigned long tmp;   // Coud be unsigned char : unsigned long has been chose to avoid any potential alignment issue with DMA 
  
    if( USBD_GetState() <  USBD_STATE_CONFIGURED) 
        tmp = 0;    // If device is unconfigured, returned configuration must be 0 
    else 
        tmp = pDriver->cfgnum; 

    USBD_Write(0, &tmp, 1, 0, 0); 
}
Exemplo n.º 15
0
/**
 * Send a NULL packet
 */
static void TerminateCtrlInWithNull(void *pArg,
                                    uint8_t status,
                                    uint32_t transferred,
                                    uint32_t remaining)
{
    USBD_Write(0, /* Endpoint #0 */
               0, /* No data buffer */
               0, /* No data buffer */
               (TransferCallback) 0,
               (void *)  0);
}
Exemplo n.º 16
0
uint32_t CDCDSerialPort_Write(const CDCDSerialPort * pCdcd,
                                   void * pData, uint32_t dwSize,
                                   TransferCallback fCallback, void * pArg)
{
    if (pCdcd->bBulkInPIPE == 0)
        return USBRC_PARAM_ERR;

    return USBD_Write(pCdcd->bBulkInPIPE,
                      pData, dwSize,
                      fCallback, pArg);
}
Exemplo n.º 17
0
//------------------------------------------------------------------------------
/// Changes the state of the serial driver according to the information
/// sent by the host via a SetControlLineState request, and acknowledges
/// the request with a zero-length packet.
//------------------------------------------------------------------------------
static void CDCDSerialDriver_SetControlLineState(unsigned char activateCarrier,
                                                 unsigned char isDTEPresent)
{
    TRACE_INFO_WP(
              "sControlLineState(%d, %d) ",
              activateCarrier,
              isDTEPresent);

    cdcdSerialDriver.isCarrierActivated = activateCarrier;
    USBD_Write(0, 0, 0, 0, 0);
}
Exemplo n.º 18
0
//-----------------------------------------------------------------------------
/// Writes to host through MSD defined bulk IN pipe. Act as USBD_Write but by
/// a fixed IN endpoint.
/// \param data Pointer to the data that writes to the host.
/// \param size The number of bytes should be write.
/// \param callback Pointer to the function invoked on end of writing.
/// \param argument Pointer to additional argument data struct.
//-----------------------------------------------------------------------------
char MSDD_Write(void *data,
                unsigned int size,
                TransferCallback callback,
                void *argument)
{
    return USBD_Write(MSDDriverDescriptors_BULKIN,
                      data,
                      size,
                      callback,
                      argument);
}
Exemplo n.º 19
0
//------------------------------------------------------------------------------
/// Send a NULL packet
//------------------------------------------------------------------------------
static void TerminateCtrlInWithNull(void *pArg,
                                    unsigned char status,
                                    unsigned int transferred,
                                    unsigned int remaining)
{
    USBD_Write(0, // Endpoint #0
               0, // No data buffer
               0, // No data buffer
               (TransferCallback) 0,
               (void *)  0);
}
Exemplo n.º 20
0
/**************************************************************************//**
 * @brief
 *   Start a USB bulk-in or bulk-out transfer to transfer a data payload
 *   to/from host.
 *
 * @param[in] data
 *   Pointer to data payload.
 *
 * @param[in] len
 *   Number of bytes to transfer.
 *
 * @param[in] cb
 *   Transfer completion callback.
 *****************************************************************************/
static void UsbXferBotData(uint8_t *data, uint32_t len,
                           USB_XferCompleteCb_TypeDef cb)
{
  if (pCmdStatus->direction)
  {
    USBD_Write(BULK_IN, data, len, cb);
  }
  else
  {
    USBD_Read(BULK_OUT, data, len, cb);
  }
}
Exemplo n.º 21
0
static int gpio_get(const USB_Setup_TypeDef *setup)
{
	CHECK_SETUP_IN(USBTHING_CMD_GPIO_GET_SIZE);

	uint8_t pin = setup->wIndex;

	struct usbthing_ctrl_s *ctrl = (struct usbthing_ctrl_s*)&cmd_buffer;

	ctrl->gpio_cmd.get.level = GPIO_get(pin);

	//TODO: respond
	return USBD_Write(0, cmd_buffer, USBTHING_CMD_GPIO_GET_SIZE, NULL);
}
Exemplo n.º 22
0
//-----------------------------------------------------------------------------
/// Sends the current line coding information to the host through Control
/// endpoint 0.
/// \param request Pointer to a USBGenericRequest instance.
//-----------------------------------------------------------------------------
static void CDCD_GetLineCoding(const USBGenericRequest *request)
{
    unsigned char serial;
    serial = CDCD_GetSerialPort(request);

    TRACE_INFO_WP("gLineCoding_%d ", serial);

    USBD_Write(0,
               (void *) &(cdcFunDriver.pCdcPorts[serial].lineCoding),
               sizeof(CDCLineCoding),
               0,
               0);
}
Exemplo n.º 23
0
//------------------------------------------------------------------------------
/// Callback triggered after the new mute status of a channel has been read
/// by AUDDSpeakerDriver_SetFeatureCurrentValue. Changes the mute status
/// of the given channel accordingly.
/// \param channel Number of the channel whose mute status has changed.
//------------------------------------------------------------------------------
static void AUDDSpeakerDriver_MuteReceived(unsigned int channel)
{
    if (muted) {
    
        AUDDSpeakerChannel_Mute(&(auddSpeakerDriver.channels[channel]));
    }
    else {

        AUDDSpeakerChannel_Unmute(&(auddSpeakerDriver.channels[channel]));
    }

    USBD_Write(0, 0, 0, 0, 0);
}
Exemplo n.º 24
0
/**
 * Write data through USB interrupt IN EP.
 * \param pData Pointer to the data sent.
 * \param dLength The data length.
 * \param fCallback Callback function invoked when transferring done.
 * \param pArg Pointer to additional arguments.
 */
uint8_t HIDDTransferDriver_Write(const void *pData,
                                 uint32_t dLength,
                                 TransferCallback fCallback,
                                 void *pArg)
{
    HIDDTransferDriver *pDrv = &hiddTransferDriver;
    if (dLength != HIDDTransferDriver_REPORTSIZE) {

        dLength = HIDDTransferDriver_REPORTSIZE;
    }
    return USBD_Write(pDrv->hidFunction.bPipeIN,
                      pData, dLength,
                      fCallback, pArg);
}
Exemplo n.º 25
0
/**
  Write data to a USB host.
  @param buffer The data to send.
  @param length How many bytes to send.
  @return The number of bytes successfully written.
  
  \b Example
  \code
  int written = UsbSerial_write( "hi hi", 5 );
  \endcode
*/
int UsbSerial_write( const char *buffer, int length, int timeout )
{
  int rv = 0;
  if( USBD_GetState() == USBD_STATE_CONFIGURED ) {
    if( USBD_Write(CDCDSerialDriverDescriptors_DATAIN, 
          buffer, length, UsbSerial_onUsbWritten, 0) == USBD_STATUS_SUCCESS ) {
      if( SemaphoreTake( usbSerial.writeSemaphore, timeout ) ) {
        rv = usbSerial.justWrote;
        usbSerial.justWrote = 0;
      }
    }
  }
  return rv;
}
Exemplo n.º 26
0
//------------------------------------------------------------------------------
/// Sends the currently active setting of the given interface to the USB
/// host. If alternate settings are not supported, this function STALLs the
/// control pipe.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param infnum  Interface number.
//------------------------------------------------------------------------------
static void GetInterface(
    const USBDDriver *pDriver,
    unsigned char infnum)
{
    // Make sure alternate settings are supported, or STALL the control pipe
    if (!pDriver->pInterfaces) {

        USBD_Stall(0);
    }
    else {

        // Sends the current interface setting to the host
        USBD_Write(0, &(pDriver->pInterfaces[infnum]), 1, 0, 0);
    }
}
Exemplo n.º 27
0
/**
 * Configures the device by setting it into the Configured state and
 * initializing all endpoints.
 * \param pDriver  Pointer to a USBDDriver instance.
 * \param cfgnum  Configuration number to set.
 */
static void SetConfiguration(USBDDriver *pDriver, uint8_t cfgnum)
{
    USBEndpointDescriptor *pEndpoints[17];
    const USBConfigurationDescriptor *pConfiguration;

    /* Use different descriptor depending on device speed */
    if (   USBD_HAL_IsHighSpeed()
        && pDriver->pDescriptors->pHsConfiguration) {

        pConfiguration = pDriver->pDescriptors->pHsConfiguration;
    }
    else {

        pConfiguration = pDriver->pDescriptors->pFsConfiguration;
    }

    /* Set & save the desired configuration */
    USBD_SetConfiguration(cfgnum);

    pDriver->cfgnum = cfgnum;
    pDriver->isRemoteWakeUpEnabled =
        ((pConfiguration->bmAttributes & 0x20) > 0);

    /* If the configuration is not 0, configure endpoints */
    if (cfgnum != 0) {

        /* Parse configuration to get endpoint descriptors */
        USBConfigurationDescriptor_Parse(pConfiguration, 0, pEndpoints, 0);

        /* Configure endpoints */
        int i = 0;
        while (pEndpoints[i] != 0) {

            USBD_ConfigureEndpoint(pEndpoints[i]);
            i++;
        }
    }
    /* Should be done before send the ZLP */
    if (NULL != USBDDriverCallbacks_ConfigurationChanged)
        USBDDriverCallbacks_ConfigurationChanged(cfgnum);

    /* Acknowledge the request */
    USBD_Write(0, /* Endpoint #0 */
               0, /* No data buffer */
               0, /* No data buffer */
               (TransferCallback) 0,
               (void *)  0);
}
Exemplo n.º 28
0
//-----------------------------------------------------------------------------
/// Changes the state of the serial driver according to the information
/// sent by the host via a SetControlLineState request, and acknowledges
/// the request with a zero-length packet.
/// \param request Pointer to a USBGenericRequest instance.
/// \param activateCarrier The active carrier state to set.
/// \param isDTEPresent The DTE status.
//-----------------------------------------------------------------------------
static void CDCD_SetControlLineState(const USBGenericRequest *request,
                                     unsigned char activateCarrier,
                                     unsigned char isDTEPresent)
{
    unsigned char serial;
    serial = CDCD_GetSerialPort(request);

    TRACE_INFO_WP(
              "sControlLineState_%d(%d, %d) ",
              serial,
              activateCarrier,
              isDTEPresent);

    cdcFunDriver.pCdcPorts[serial].isCarrierActivated = activateCarrier;
    USBD_Write(0, 0, 0, 0, 0);
}
Exemplo n.º 29
0
//-----------------------------------------------------------------------------
/// Sends a data buffer through the virtual COM port created by the CDC
/// function serial driver. This function behaves exactly like <USBD_Write>.
/// \param port Port index to receive.
/// \param  data - Pointer to the data buffer to send.
/// \param  size - Size of the data buffer in bytes.
/// \param  callback - Optional callback function to invoke when the transfer
///         finishes.
/// \param  argument - Optional argument to the callback function.
/// \return <USBD_STATUS_SUCCESS> if the write operation started normally;
///         otherwise, the corresponding error code.
//-----------------------------------------------------------------------------
unsigned char CDCDSerialDriver_Write(unsigned char port,
                                     void *data,
                                     unsigned int size,
                                     TransferCallback callback,
                                     void *argument)
{
    unsigned char ep = cdcFunDriver.pCdcPorts[port].bulkInEndpoint;

    if (port > cdcFunDriver.numPorts)
        return USBD_STATUS_INVALID_PARAMETER;

    return USBD_Write(ep,
                      data,
                      size,
                      callback,
                      argument);
}
Exemplo n.º 30
0
/**
 * Callback function which should be invoked after the data of a
 * SetLineCoding request has been retrieved. Sends a zero-length packet
 * to the host for acknowledging the request.
 * \param pCdcd Pointer to CDCDSerialPort instance.
 */
static void _SetLineCodingCallback(CDCDSerialPort * pCdcd)
{
    uint32_t exec = 1;
    if (pCdcd->fEventHandler) {
        uint32_t rc = pCdcd->fEventHandler(
                          CDCDSerialPortEvent_SETLINECODING,
                          (uint32_t)(&lineCoding),
                          pCdcd->pArg);
        if (rc == USBD_STATUS_SUCCESS) {
            pCdcd->lineCoding.dwDTERate   = lineCoding.dwDTERate;
            pCdcd->lineCoding.bCharFormat = lineCoding.bCharFormat;
            pCdcd->lineCoding.bParityType = lineCoding.bParityType;
            pCdcd->lineCoding.bDataBits   = lineCoding.bDataBits;
        } else
            exec = 0;
    }
    if (exec)   USBD_Write(0, 0, 0, 0, 0);
    else        USBD_Stall(0);
}