/*\r
- LPCUSB, an USB device driver for LPC microcontrollers \r
+ LPCUSB, an USB device driver for LPC microcontrollers\r
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)\r
\r
Redistribution and use in source and binary forms, with or without\r
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
*/\r
\r
#include "FreeRTOS.h"\r
+#include "task.h"\r
#include "queue.h"\r
\r
#include <stdio.h>\r
0x02, // bmAttributes = bulk\r
LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize\r
0x00, // bInterval\r
- \r
+\r
// string descriptors\r
0x04,\r
DESC_STRING,\r
\r
/**\r
Local function to handle incoming bulk data\r
- \r
+\r
@param [in] bEP\r
@param [in] bEPStatus\r
*/\r
long lHigherPriorityTaskWoken = pdFALSE;\r
\r
( void ) bEPStatus;\r
- \r
+\r
// get data from USB into intermediate buffer\r
iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));\r
for (i = 0; i < iLen; i++) {\r
// put into queue\r
- xQueueSendFromISR( xRxedChars, &( abBulkBuf[ i ] ), &lHigherPriorityTaskWoken ); \r
+ xQueueSendFromISR( xRxedChars, &( abBulkBuf[ i ] ), &lHigherPriorityTaskWoken );\r
}\r
- \r
+\r
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
}\r
\r
\r
/**\r
Local function to handle outgoing bulk data\r
- \r
+\r
@param [in] bEP\r
@param [in] bEPStatus\r
*/\r
long lHigherPriorityTaskWoken = pdFALSE;\r
\r
( void ) bEPStatus;\r
- \r
+\r
if (uxQueueMessagesWaitingFromISR( xCharsForTx ) == 0) {\r
// no more data, disable further NAK interrupts until next USB frame\r
USBHwNakIntEnable(0);\r
}\r
}\r
iLen = i;\r
- \r
+\r
// send over USB\r
if (iLen > 0) {\r
USBHwEPWrite(bEP, abBulkBuf, iLen);\r
}\r
- \r
+\r
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
}\r
\r
\r
/**\r
Local function to handle the USB-CDC class requests\r
- \r
+\r
@param [in] pSetup\r
@param [out] piLen\r
@param [out] ppbData\r
\r
/**\r
Writes one character to VCOM port\r
- \r
+\r
@param [in] c character to write\r
@returns character written, or EOF if character could not be written\r
*/\r
\r
/**\r
Reads one character from VCOM port\r
- \r
+\r
@returns character read, or EOF if character could not be read\r
*/\r
int VCOM_getchar(void)\r
{\r
unsigned char c;\r
- \r
+\r
/* Block the task until a character is available. */\r
xQueueReceive( xRxedChars, &c, portMAX_DELAY );\r
return c;\r
\r
/**\r
Interrupt handler\r
- \r
+\r
Simply calls the USB ISR\r
*/\r
//void USBIntHandler(void)\r
static void USBFrameHandler(unsigned short wFrame)\r
{\r
( void ) wFrame;\r
- \r
+\r
if( uxQueueMessagesWaitingFromISR( xCharsForTx ) > 0 )\r
{\r
// data available, enable NAK interrupt on bulk in\r
void vUSBTask( void *pvParameters )\r
{\r
int c;\r
- \r
+\r
/* Just to prevent compiler warnings about the unused parameter. */\r
( void ) pvParameters;\r
DBG("Initialising USB stack\n");\r
anything so just delete ourselves. */\r
vTaskDelete( NULL );\r
}\r
- \r
- \r
+\r
+\r
// initialise stack\r
USBInit();\r
\r
USBHwRegisterEPIntHandler(INT_IN_EP, NULL);\r
USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn);\r
USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut);\r
- \r
+\r
// register frame handler\r
USBHwRegisterFrameHandler(USBFrameHandler);\r
\r
\r
NVIC_SetPriority( USB_IRQn, configUSB_INTERRUPT_PRIORITY );\r
NVIC_EnableIRQ( USB_IRQn );\r
- \r
+\r
// connect to bus\r
- \r
+\r
DBG("Connecting to USB bus\n");\r
USBHwConnect(TRUE);\r
\r
for( ;; )\r
{\r
c = VCOM_getchar();\r
- if (c != EOF) \r
+ if (c != EOF)\r
{\r
// Echo character back with INCREMENT_ECHO_BY offset, so for example if\r
// INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back.\r
/*
- LPCUSB, an USB device driver for LPC microcontrollers
+ LPCUSB, an USB device driver for LPC microcontrollers
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
Redistribution and use in source and binary forms, with or without
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
/** @file
Control transfer handler.
-
+
This module handles control transfers and is normally installed on the
endpoint 0 callback.
-
+
Control transfers can be of the following type:
0 Standard;
1 Class;
/**
Local function to handle a request by calling one of the installed
request handlers.
-
+
In case of data going from host to device, the data is at *ppbData.
In case of data going from device to host, the handler can either
choose to write its data at *ppbData or update the data pointer.
-
+
@param [in] pSetup The setup packet
@param [in,out] *piLen Pointer to data length
@param [in,out] ppbData Data buffer.
{
TFnHandleRequest *pfnHandler;
int iType;
-
+
iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
pfnHandler = apfnReqHandlers[iType];
if (pfnHandler == NULL) {
/**
Local function to stall the control endpoint
-
+
@param [in] bEPStat Endpoint status
*/
static void StallControlPipe(unsigned char bEPStat)
unsigned char *pb;
int i;
+ ( void ) bEPStat;
USBHwEPStall(0x80, TRUE);
// dump setup packet
DataIn();
}
}
- else {
+ else {
if (iResidue > 0) {
// store data
iChunk = USBHwEPRead(0x00, pbData, iResidue);
/**
Registers a callback for handling requests
-
+
@param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD
@param [in] *pfnHandler Callback function pointer
@param [in] *pbDataStore Data storage area for this type of request
/*\r
- LPCUSB, an USB device driver for LPC microcontrollers \r
+ LPCUSB, an USB device driver for LPC microcontrollers\r
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)\r
\r
Redistribution and use in source and binary forms, with or without\r
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
\r
/** @file\r
Standard request handler.\r
- \r
+\r
This modules handles the 'chapter 9' processing, specifically the\r
standard device requests in table 9-3 from the universal serial bus\r
specification revision 2.0\r
- \r
+\r
Specific types of devices may specify additional requests (for example\r
HID devices add a GET_DESCRIPTOR request for interfaces), but they\r
will not be part of this module.\r
@todo some requests have to return a request error if device not configured:\r
@todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME\r
@todo this applies to the following if endpoint != 0:\r
- @todo SET_FEATURE, GET_FEATURE \r
+ @todo SET_FEATURE, GET_FEATURE\r
*/\r
\r
#include "usbdebug.h"\r
\r
/* general descriptor field offsets */\r
#define DESC_bLength 0 /**< length offset */\r
-#define DESC_bDescriptorType 1 /**< descriptor type offset */ \r
+#define DESC_bDescriptorType 1 /**< descriptor type offset */\r
\r
/* config descriptor field offsets */\r
#define CONF_DESC_wTotalLength 2 /**< total length offset */\r
-#define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */ \r
+#define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */\r
#define CONF_DESC_bmAttributes 7 /**< configuration characteristics */\r
\r
/* interface descriptor field offsets */\r
/**\r
Parses the list of installed USB descriptors and attempts to find\r
the specified USB descriptor.\r
- \r
+\r
@param [in] wTypeIndex Type and index of the descriptor\r
@param [in] wLangID Language ID of the descriptor (currently unused)\r
@param [out] *piLen Descriptor length\r
@param [out] *ppbData Descriptor data\r
- \r
+\r
@return TRUE if the descriptor was found, FALSE otherwise\r
*/\r
BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData)\r
unsigned char bType, bIndex;\r
unsigned char *pab;\r
int iCurIndex;\r
- \r
+\r
+ ( void ) wLangID;\r
ASSERT(pabDescrip != NULL);\r
\r
bType = GET_DESC_TYPE(wTypeIndex);\r
bIndex = GET_DESC_INDEX(wTypeIndex);\r
- \r
+\r
pab = (unsigned char *)pabDescrip;\r
iCurIndex = 0;\r
- \r
+\r
while (pab[DESC_bLength] != 0) {\r
if (pab[DESC_bDescriptorType] == bType) {\r
if (iCurIndex == bIndex) {\r
Configures the device according to the specified configuration index and\r
alternate setting by parsing the installed USB descriptor list.\r
A configuration index of 0 unconfigures the device.\r
- \r
+\r
@param [in] bConfigIndex Configuration index\r
@param [in] bAltSetting Alternate setting number\r
- \r
+\r
@todo function always returns TRUE, add stricter checking?\r
- \r
+\r
@return TRUE if successfully configured, FALSE otherwise\r
*/\r
static BOOL USBSetConfiguration(unsigned char bConfigIndex, unsigned char bAltSetting)\r
unsigned char bCurConfig, bCurAltSetting;\r
unsigned char bEP;\r
unsigned short wMaxPktSize;\r
- \r
+\r
ASSERT(pabDescrip != NULL);\r
\r
if (bConfigIndex == 0) {\r
// skip to next descriptor\r
pab += pab[DESC_bLength];\r
}\r
- \r
+\r
// configure device\r
USBHwConfigDevice(TRUE);\r
}\r
\r
/**\r
Local function to handle a standard device request\r
- \r
+\r
@param [in] pSetup The setup packet\r
@param [in,out] *piLen Pointer to data length\r
@param [in,out] ppbData Data buffer.\r
unsigned char *pbData = *ppbData;\r
\r
switch (pSetup->bRequest) {\r
- \r
+\r
case REQ_GET_STATUS:\r
// bit 0: self-powered\r
// bit 1: remote wakeup = not supported\r
pbData[1] = 0;\r
*piLen = 2;\r
break;\r
- \r
+\r
case REQ_SET_ADDRESS:\r
USBHwSetAddress(pSetup->wValue);\r
break;\r
return FALSE;\r
}\r
// configuration successful, update current configuration\r
- bConfiguration = pSetup->wValue & 0xFF; \r
+ bConfiguration = pSetup->wValue & 0xFF;\r
break;\r
\r
case REQ_CLEAR_FEATURE:\r
DBG("Illegal device req %d\n", pSetup->bRequest);\r
return FALSE;\r
}\r
- \r
+\r
return TRUE;\r
}\r
\r
\r
/**\r
Local function to handle a standard interface request\r
- \r
+\r
@param [in] pSetup The setup packet\r
@param [in,out] *piLen Pointer to data length\r
@param [in] ppbData Data buffer.\r
case REQ_SET_FEATURE:\r
// not defined for interface\r
return FALSE;\r
- \r
+\r
case REQ_GET_INTERFACE: // TODO use bNumInterfaces\r
// there is only one interface, return n-1 (= 0)\r
pbData[0] = 0;\r
*piLen = 1;\r
break;\r
- \r
+\r
case REQ_SET_INTERFACE: // TODO use bNumInterfaces\r
// there is only one interface (= 0)\r
if (pSetup->wValue != 0) {\r
\r
/**\r
Local function to handle a standard endpoint request\r
- \r
+\r
@param [in] pSetup The setup packet\r
@param [in,out] *piLen Pointer to data length\r
@param [in] ppbData Data buffer.\r
pbData[1] = 0;\r
*piLen = 2;\r
break;\r
- \r
+\r
case REQ_CLEAR_FEATURE:\r
if (pSetup->wValue == FEA_ENDPOINT_HALT) {\r
// clear HALT by unstalling\r
}\r
// only ENDPOINT_HALT defined for endpoints\r
return FALSE;\r
- \r
+\r
case REQ_SET_FEATURE:\r
if (pSetup->wValue == FEA_ENDPOINT_HALT) {\r
// set HALT by stalling\r
DBG("Illegal EP req %d\n", pSetup->bRequest);\r
return FALSE;\r
}\r
- \r
+\r
return TRUE;\r
}\r
\r
\r
/**\r
Default handler for standard ('chapter 9') requests\r
- \r
+\r
If a custom request handler was installed, this handler is called first.\r
- \r
+\r
@param [in] pSetup The setup packet\r
@param [in,out] *piLen Pointer to data length\r
@param [in] ppbData Data buffer.\r
if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {\r
return TRUE;\r
}\r
- \r
+\r
switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {\r
case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData);\r
case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData);\r
\r
/**\r
Registers a callback for custom device requests\r
- \r
+\r
In USBHandleStandardRequest, the custom request handler gets a first\r
chance at handling the request before it is handed over to the 'chapter 9'\r
request handler.\r
- \r
+\r
This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR\r
request is sent to an interface, which is not covered by the 'chapter 9'\r
specification.\r
- \r
+\r
@param [in] pfnHandler Callback function pointer\r
*/\r
void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)\r