1
0
mirror of https://github.com/elua/elua.git synced 2025-01-25 01:02:54 +08:00

Bring type definitions in line with eLua standard conventions.

This commit is contained in:
Andreas Bogk 2015-04-23 16:23:08 +02:00
parent cc425be821
commit 480d6352ea
7 changed files with 1088 additions and 1204 deletions

View File

@ -1,8 +1,10 @@
-- Configuration file for the LPC17xx backend -- Configuration file for the LPC17xx backend
addi( sf( 'src/platform/%s/drivers/inc', platform ) ) addi( sf( 'src/platform/%s/drivers/inc', platform ) )
addi( sf( 'src/platform/%s/usbstack/inc', platform ) )
local fwlib_files = utils.get_files( sf( "src/platform/%s/drivers/src", platform ), ".*%.c$" ) local fwlib_files = utils.get_files( sf( "src/platform/%s/drivers/src", platform ), ".*%.c$" )
fwlib_files = fwlib_files .. " " .. utils.get_files( sf( "src/platform/%s/usbstack/src", platform ), ".*%.c$" )
specific_files = "startup_LPC17xx.c system_LPC17xx.c core_cm3.c platform.c" specific_files = "startup_LPC17xx.c system_LPC17xx.c core_cm3.c platform.c"
local board = comp.board:upper() local board = comp.board:upper()

View File

@ -1,68 +0,0 @@
/*
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
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
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,
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
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@file
primitive types used in the USB stack
*/
// ***********************************************
// Code Red Technologies - port to RDB1768 board
// In order to avoid clashing with the NXP-produced type.h file, this
// one has been renamed to lpcusb_type.h, the NXP-produced type.h has
// been included, and the duplicate contents of this file commented out.
// ***********************************************
#ifndef _LPCUSB_TYPE_H_
#define _LPCUSB_TYPE_H_
// CodeRed - include NXP-produced type.h file
#include "type.h"
typedef unsigned char U8; /**< unsigned 8-bit */
typedef unsigned short int U16; /**< unsigned 16-bit */
typedef unsigned int U32; /**< unsigned 32-bit */
// CodeRed - comment out defines duplicated in NXP type.h
//typedef int BOOL; /**< #TRUE or #FALSE */
//#define TRUE 1 /**< TRUE */
//#define FALSE 0 /**< FALSE */
//#ifndef NULL
//#define NULL ((void*)0) /**< NULL pointer */
//#endif
//#endif
/* some other useful macros */
#define MIN(x,y) ((x)<(y)?(x):(y)) /**< MIN */
#define MAX(x,y) ((x)>(y)?(x):(y)) /**< MAX */
#endif /* _LPCUSB_TYPE_H_ */

View File

@ -1,38 +0,0 @@
/*****************************************************************************
* type.h: Type definition Header file for NXP LPC17xx Family
* Microprocessors
*
* Copyright(C) 2008, NXP Semiconductor
* All rights reserved.
*
* History
* 2008.08.21 ver 1.00 Prelimnary version, first Release
*
******************************************************************************/
#ifndef __TYPE_H__
#define __TYPE_H__
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (1)
#endif
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned int BOOL;
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
/* Pointer to Function returning Void (any number of parameters) */
typedef void (*PFV)();
#endif /* __TYPE_H__ */

View File

@ -1,5 +1,5 @@
/* /*
LPCUSB, an USB device driver for LPC microcontrollers LPCUSB, an USB device driver for LPC microcontrollers
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -16,7 +16,7 @@
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 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 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
@ -28,10 +28,10 @@
/** @file /** @file
Control transfer handler. Control transfer handler.
This module handles control transfers and is normally installed on the This module handles control transfers and is normally installed on the
endpoint 0 callback. endpoint 0 callback.
Control transfers can be of the following type: Control transfers can be of the following type:
0 Standard; 0 Standard;
1 Class; 1 Class;
@ -48,9 +48,7 @@
control transfer data. The data is then packetised and sent to the host. control transfer data. The data is then packetised and sent to the host.
*/ */
// CodeRed - include the LPCUSB type.h file rather than NXP one directly #include "type.h"
//#include "type.h"
#include "lpcusb_type.h"
#include "usbdebug.h" #include "usbdebug.h"
@ -64,34 +62,34 @@
static TSetupPacket Setup; /**< setup packet */ static TSetupPacket Setup; /**< setup packet */
static U8 *pbData; /**< pointer to data buffer */ static u8 *pbData; /**< pointer to data buffer */
static int iResidue; /**< remaining bytes in buffer */ static int iResidue; /**< remaining bytes in buffer */
static int iLen; /**< total length of control transfer */ static int iLen; /**< total length of control transfer */
/** Array of installed request handler callbacks */ /** Array of installed request handler callbacks */
static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL}; static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
/** Array of installed request data pointers */ /** Array of installed request data pointers */
static U8 *apbDataStore[4] = {NULL, NULL, NULL, NULL}; static u8 *apbDataStore[4] = {NULL, NULL, NULL, NULL};
/** /**
Local function to handle a request by calling one of the installed Local function to handle a request by calling one of the installed
request handlers. request handlers.
In case of data going from host to device, the data is at *ppbData. 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 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. choose to write its data at *ppbData or update the data pointer.
@param [in] pSetup The setup packet @param [in] pSetup The setup packet
@param [in,out] *piLen Pointer to data length @param [in,out] *piLen Pointer to data length
@param [in,out] ppbData Data buffer. @param [in,out] ppbData Data buffer.
@return TRUE if the request was handles successfully @return TRUE if the request was handles successfully
*/ */
static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData) static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, u8 **ppbData)
{ {
TFnHandleRequest *pfnHandler; TFnHandleRequest *pfnHandler;
int iType; int iType;
iType = REQTYPE_GET_TYPE(pSetup->bmRequestType); iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
pfnHandler = apfnReqHandlers[iType]; pfnHandler = apfnReqHandlers[iType];
if (pfnHandler == NULL) { if (pfnHandler == NULL) {
@ -105,19 +103,19 @@ static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
/** /**
Local function to stall the control endpoint Local function to stall the control endpoint
@param [in] bEPStat Endpoint status @param [in] bEPStat Endpoint status
*/ */
static void StallControlPipe(U8 bEPStat) static void StallControlPipe(u8 bEPStat)
{ {
U8 *pb; u8 *pb;
int i; int i;
USBHwEPStall(0x80, TRUE); USBHwEPStall(0x80, TRUE);
// dump setup packet // dump setup packet
DBG("STALL on ["); DBG("STALL on [");
pb = (U8 *)&Setup; pb = (u8 *)&Setup;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
DBG(" %02x", *pb++); DBG(" %02x", *pb++);
} }
@ -145,7 +143,7 @@ static void DataIn(void)
* @param [in] bEP Endpoint address * @param [in] bEP Endpoint address
* @param [in] bEPStat Endpoint status * @param [in] bEPStat Endpoint status
*/ */
void USBHandleControlTransfer(U8 bEP, U8 bEPStat) void USBHandleControlTransfer(u8 bEP, u8 bEPStat)
{ {
int iChunk, iType; int iChunk, iType;
@ -153,7 +151,7 @@ void USBHandleControlTransfer(U8 bEP, U8 bEPStat)
// OUT transfer // OUT transfer
if (bEPStat & EP_STATUS_SETUP) { if (bEPStat & EP_STATUS_SETUP) {
// setup packet, reset request message state machine // setup packet, reset request message state machine
USBHwEPRead(0x00, (U8 *)&Setup, sizeof(Setup)); USBHwEPRead(0x00, (u8 *)&Setup, sizeof(Setup));
DBG("S%x", Setup.bRequest); DBG("S%x", Setup.bRequest);
// defaults for data pointer and residue // defaults for data pointer and residue
@ -176,7 +174,7 @@ void USBHandleControlTransfer(U8 bEP, U8 bEPStat)
DataIn(); DataIn();
} }
} }
else { else {
if (iResidue > 0) { if (iResidue > 0) {
// store data // store data
iChunk = USBHwEPRead(0x00, pbData, iResidue); iChunk = USBHwEPRead(0x00, pbData, iResidue);
@ -219,16 +217,15 @@ void USBHandleControlTransfer(U8 bEP, U8 bEPStat)
/** /**
Registers a callback for handling requests Registers a callback for handling requests
@param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD @param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD
@param [in] *pfnHandler Callback function pointer @param [in] *pfnHandler Callback function pointer
@param [in] *pbDataStore Data storage area for this type of request @param [in] *pbDataStore Data storage area for this type of request
*/ */
void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, U8 *pbDataStore) void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, u8 *pbDataStore)
{ {
ASSERT(iType >= 0); ASSERT(iType >= 0);
ASSERT(iType < 4); ASSERT(iType < 4);
apfnReqHandlers[iType] = pfnHandler; apfnReqHandlers[iType] = pfnHandler;
apbDataStore[iType] = pbDataStore; apbDataStore[iType] = pbDataStore;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
LPCUSB, an USB device driver for LPC microcontrollers LPCUSB, an USB device driver for LPC microcontrollers
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -16,7 +16,7 @@
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 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 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
@ -30,24 +30,22 @@
USB stack initialisation USB stack initialisation
*/ */
// CodeRed - include the LPCUSB type.h file rather than NXP one directly #include "type.h"
//#include "type.h"
#include "lpcusb_type.h"
#include "usbdebug.h" #include "usbdebug.h"
#include "usbapi.h" #include "usbapi.h"
/** data storage area for standard requests */ /** data storage area for standard requests */
static U8 abStdReqData[8]; static u8 abStdReqData[8];
/** /**
USB reset handler USB reset handler
@param [in] bDevStatus Device status @param [in] bDevStatus Device status
*/ */
static void HandleUsbReset(U8 bDevStatus) static void HandleUsbReset(u8 bDevStatus)
{ {
if (bDevStatus & DEV_STATUS_RESET) { if (bDevStatus & DEV_STATUS_RESET) {
DBG("\n!"); DBG("\n!");
@ -58,28 +56,27 @@ static void HandleUsbReset(U8 bDevStatus)
/** /**
Initialises the USB hardware and sets up the USB stack by Initialises the USB hardware and sets up the USB stack by
installing default callbacks. installing default callbacks.
@return TRUE if initialisation was successful @return TRUE if initialisation was successful
*/ */
BOOL USBInit(void) BOOL USBInit(void)
{ {
// init hardware // init hardware
USBHwInit(); USBHwInit();
// register bus reset handler // register bus reset handler
USBHwRegisterDevIntHandler(HandleUsbReset); USBHwRegisterDevIntHandler(HandleUsbReset);
// register control transfer handler on EP0 // register control transfer handler on EP0
USBHwRegisterEPIntHandler(0x00, USBHandleControlTransfer); USBHwRegisterEPIntHandler(0x00, USBHandleControlTransfer);
USBHwRegisterEPIntHandler(0x80, USBHandleControlTransfer); USBHwRegisterEPIntHandler(0x80, USBHandleControlTransfer);
// setup control endpoints // setup control endpoints
USBHwEPConfig(0x00, MAX_PACKET_SIZE0); USBHwEPConfig(0x00, MAX_PACKET_SIZE0);
USBHwEPConfig(0x80, MAX_PACKET_SIZE0); USBHwEPConfig(0x80, MAX_PACKET_SIZE0);
// register standard request handler // register standard request handler
USBRegisterRequestHandler(REQTYPE_TYPE_STANDARD, USBHandleStandardRequest, abStdReqData); USBRegisterRequestHandler(REQTYPE_TYPE_STANDARD, USBHandleStandardRequest, abStdReqData);
return TRUE; return TRUE;
} }

View File

@ -1,434 +1,431 @@
/* /*
LPCUSB, an USB device driver for LPC microcontrollers LPCUSB, an USB device driver for LPC microcontrollers
Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 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 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file /** @file
Standard request handler. Standard request handler.
This modules handles the 'chapter 9' processing, specifically the This modules handles the 'chapter 9' processing, specifically the
standard device requests in table 9-3 from the universal serial bus standard device requests in table 9-3 from the universal serial bus
specification revision 2.0 specification revision 2.0
Specific types of devices may specify additional requests (for example Specific types of devices may specify additional requests (for example
HID devices add a GET_DESCRIPTOR request for interfaces), but they HID devices add a GET_DESCRIPTOR request for interfaces), but they
will not be part of this module. will not be part of this module.
@todo some requests have to return a request error if device not configured: @todo some requests have to return a request error if device not configured:
@todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME @todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME
@todo this applies to the following if endpoint != 0: @todo this applies to the following if endpoint != 0:
@todo SET_FEATURE, GET_FEATURE @todo SET_FEATURE, GET_FEATURE
*/ */
// CodeRed - include the LPCUSB type.h file rather than NXP one directly #include "type.h"
//#include "type.h"
#include "lpcusb_type.h" #include "usbdebug.h"
#include "usbstruct.h"
#include "usbdebug.h" #include "usbapi.h"
#include "usbstruct.h"
#include "usbapi.h" #define MAX_DESC_HANDLERS 4 /**< device, interface, endpoint, other */
#define MAX_DESC_HANDLERS 4 /**< device, interface, endpoint, other */
/* general descriptor field offsets */
#define DESC_bLength 0 /**< length offset */
/* general descriptor field offsets */ #define DESC_bDescriptorType 1 /**< descriptor type offset */
#define DESC_bLength 0 /**< length offset */
#define DESC_bDescriptorType 1 /**< descriptor type offset */ /* config descriptor field offsets */
#define CONF_DESC_wTotalLength 2 /**< total length offset */
/* config descriptor field offsets */ #define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */
#define CONF_DESC_wTotalLength 2 /**< total length offset */ #define CONF_DESC_bmAttributes 7 /**< configuration characteristics */
#define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */
#define CONF_DESC_bmAttributes 7 /**< configuration characteristics */ /* interface descriptor field offsets */
#define INTF_DESC_bAlternateSetting 3 /**< alternate setting offset */
/* interface descriptor field offsets */
#define INTF_DESC_bAlternateSetting 3 /**< alternate setting offset */ /* endpoint descriptor field offsets */
#define ENDP_DESC_bEndpointAddress 2 /**< endpoint address offset */
/* endpoint descriptor field offsets */ #define ENDP_DESC_wMaxPacketSize 4 /**< maximum packet size offset */
#define ENDP_DESC_bEndpointAddress 2 /**< endpoint address offset */
#define ENDP_DESC_wMaxPacketSize 4 /**< maximum packet size offset */
/** Currently selected configuration */
static u8 bConfiguration = 0;
/** Currently selected configuration */ /** Installed custom request handler */
static U8 bConfiguration = 0; static TFnHandleRequest *pfnHandleCustomReq = NULL;
/** Installed custom request handler */ /** Pointer to registered descriptors */
static TFnHandleRequest *pfnHandleCustomReq = NULL; static const u8 *pabDescrip = NULL;
/** Pointer to registered descriptors */
static const U8 *pabDescrip = NULL;
/**
Registers a pointer to a descriptor block containing all descriptors
/** for the device.
Registers a pointer to a descriptor block containing all descriptors
for the device. @param [in] pabDescriptors The descriptor byte array
*/
@param [in] pabDescriptors The descriptor byte array void USBRegisterDescriptors(const u8 *pabDescriptors)
*/ {
void USBRegisterDescriptors(const U8 *pabDescriptors) pabDescrip = pabDescriptors;
{ }
pabDescrip = pabDescriptors;
}
/**
Parses the list of installed USB descriptors and attempts to find
/** the specified USB descriptor.
Parses the list of installed USB descriptors and attempts to find
the specified USB descriptor. @param [in] wTypeIndex Type and index of the descriptor
@param [in] wLangID Language ID of the descriptor (currently unused)
@param [in] wTypeIndex Type and index of the descriptor @param [out] *piLen Descriptor length
@param [in] wLangID Language ID of the descriptor (currently unused) @param [out] *ppbData Descriptor data
@param [out] *piLen Descriptor length
@param [out] *ppbData Descriptor data @return TRUE if the descriptor was found, FALSE otherwise
*/
@return TRUE if the descriptor was found, FALSE otherwise BOOL USBGetDescriptor(u16 wTypeIndex, u16 wLangID, int *piLen, u8 **ppbData)
*/ {
BOOL USBGetDescriptor(U16 wTypeIndex, U16 wLangID, int *piLen, U8 **ppbData) u8 bType, bIndex;
{ u8 *pab;
U8 bType, bIndex; int iCurIndex;
U8 *pab;
int iCurIndex; ASSERT(pabDescrip != NULL);
ASSERT(pabDescrip != NULL); bType = GET_DESC_TYPE(wTypeIndex);
bIndex = GET_DESC_INDEX(wTypeIndex);
bType = GET_DESC_TYPE(wTypeIndex);
bIndex = GET_DESC_INDEX(wTypeIndex); pab = (u8 *)pabDescrip;
iCurIndex = 0;
pab = (U8 *)pabDescrip;
iCurIndex = 0; while (pab[DESC_bLength] != 0) {
if (pab[DESC_bDescriptorType] == bType) {
while (pab[DESC_bLength] != 0) { if (iCurIndex == bIndex) {
if (pab[DESC_bDescriptorType] == bType) { // set data pointer
if (iCurIndex == bIndex) { *ppbData = pab;
// set data pointer // get length from structure
*ppbData = pab; if (bType == DESC_CONFIGURATION) {
// get length from structure // configuration descriptor is an exception, length is at offset 2 and 3
if (bType == DESC_CONFIGURATION) { *piLen = (pab[CONF_DESC_wTotalLength]) |
// configuration descriptor is an exception, length is at offset 2 and 3 (pab[CONF_DESC_wTotalLength + 1] << 8);
*piLen = (pab[CONF_DESC_wTotalLength]) | }
(pab[CONF_DESC_wTotalLength + 1] << 8); else {
} // normally length is at offset 0
else { *piLen = pab[DESC_bLength];
// normally length is at offset 0 }
*piLen = pab[DESC_bLength]; return TRUE;
} }
return TRUE; iCurIndex++;
} }
iCurIndex++; // skip to next descriptor
} pab += pab[DESC_bLength];
// skip to next descriptor }
pab += pab[DESC_bLength]; // nothing found
} DBG("Desc %x not found!\n", wTypeIndex);
// nothing found return FALSE;
DBG("Desc %x not found!\n", wTypeIndex); }
return FALSE;
}
/**
Configures the device according to the specified configuration index and
/** alternate setting by parsing the installed USB descriptor list.
Configures the device according to the specified configuration index and A configuration index of 0 unconfigures the device.
alternate setting by parsing the installed USB descriptor list.
A configuration index of 0 unconfigures the device. @param [in] bConfigIndex Configuration index
@param [in] bAltSetting Alternate setting number
@param [in] bConfigIndex Configuration index
@param [in] bAltSetting Alternate setting number @todo function always returns TRUE, add stricter checking?
@todo function always returns TRUE, add stricter checking? @return TRUE if successfully configured, FALSE otherwise
*/
@return TRUE if successfully configured, FALSE otherwise static BOOL USBSetConfiguration(u8 bConfigIndex, u8 bAltSetting)
*/ {
static BOOL USBSetConfiguration(U8 bConfigIndex, U8 bAltSetting) u8 *pab;
{ u8 bCurConfig, bCurAltSetting;
U8 *pab; u8 bEP;
U8 bCurConfig, bCurAltSetting; u16 wMaxPktSize;
U8 bEP;
U16 wMaxPktSize; ASSERT(pabDescrip != NULL);
ASSERT(pabDescrip != NULL); if (bConfigIndex == 0) {
// unconfigure device
if (bConfigIndex == 0) { USBHwConfigDevice(FALSE);
// unconfigure device }
USBHwConfigDevice(FALSE); else {
} // configure endpoints for this configuration/altsetting
else { pab = (u8 *)pabDescrip;
// configure endpoints for this configuration/altsetting bCurConfig = 0xFF;
pab = (U8 *)pabDescrip; bCurAltSetting = 0xFF;
bCurConfig = 0xFF;
bCurAltSetting = 0xFF; while (pab[DESC_bLength] != 0) {
while (pab[DESC_bLength] != 0) { switch (pab[DESC_bDescriptorType]) {
switch (pab[DESC_bDescriptorType]) { case DESC_CONFIGURATION:
// remember current configuration index
case DESC_CONFIGURATION: bCurConfig = pab[CONF_DESC_bConfigurationValue];
// remember current configuration index break;
bCurConfig = pab[CONF_DESC_bConfigurationValue];
break; case DESC_INTERFACE:
// remember current alternate setting
case DESC_INTERFACE: bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
// remember current alternate setting break;
bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
break; case DESC_ENDPOINT:
if ((bCurConfig == bConfigIndex) &&
case DESC_ENDPOINT: (bCurAltSetting == bAltSetting)) {
if ((bCurConfig == bConfigIndex) && // endpoint found for desired config and alternate setting
(bCurAltSetting == bAltSetting)) { bEP = pab[ENDP_DESC_bEndpointAddress];
// endpoint found for desired config and alternate setting wMaxPktSize = (pab[ENDP_DESC_wMaxPacketSize]) |
bEP = pab[ENDP_DESC_bEndpointAddress]; (pab[ENDP_DESC_wMaxPacketSize + 1] << 8);
wMaxPktSize = (pab[ENDP_DESC_wMaxPacketSize]) | // configure endpoint
(pab[ENDP_DESC_wMaxPacketSize + 1] << 8); USBHwEPConfig(bEP, wMaxPktSize);
// configure endpoint }
USBHwEPConfig(bEP, wMaxPktSize); break;
}
break; default:
break;
default: }
break; // skip to next descriptor
} pab += pab[DESC_bLength];
// skip to next descriptor }
pab += pab[DESC_bLength];
} // configure device
USBHwConfigDevice(TRUE);
// configure device }
USBHwConfigDevice(TRUE);
} return TRUE;
}
return TRUE;
}
/**
Local function to handle a standard device request
/**
Local function to handle a standard device request @param [in] pSetup The setup packet
@param [in,out] *piLen Pointer to data length
@param [in] pSetup The setup packet @param [in,out] ppbData Data buffer.
@param [in,out] *piLen Pointer to data length
@param [in,out] ppbData Data buffer. @return TRUE if the request was handled successfully
*/
@return TRUE if the request was handled successfully static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, u8 **ppbData)
*/ {
static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData) u8 *pbData = *ppbData;
{
U8 *pbData = *ppbData; switch (pSetup->bRequest) {
switch (pSetup->bRequest) { case REQ_GET_STATUS:
// bit 0: self-powered
case REQ_GET_STATUS: // bit 1: remote wakeup = not supported
// bit 0: self-powered pbData[0] = 0;
// bit 1: remote wakeup = not supported pbData[1] = 0;
pbData[0] = 0; *piLen = 2;
pbData[1] = 0; break;
*piLen = 2;
break; case REQ_SET_ADDRESS:
USBHwSetAddress(pSetup->wValue);
case REQ_SET_ADDRESS: break;
USBHwSetAddress(pSetup->wValue);
break; case REQ_GET_DESCRIPTOR:
DBG("D%x", pSetup->wValue);
case REQ_GET_DESCRIPTOR: return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);
DBG("D%x", pSetup->wValue);
return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData); case REQ_GET_CONFIGURATION:
// indicate if we are configured
case REQ_GET_CONFIGURATION: pbData[0] = bConfiguration;
// indicate if we are configured *piLen = 1;
pbData[0] = bConfiguration; break;
*piLen = 1;
break; case REQ_SET_CONFIGURATION:
if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {
case REQ_SET_CONFIGURATION: DBG("USBSetConfiguration failed!\n");
if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) { return FALSE;
DBG("USBSetConfiguration failed!\n"); }
return FALSE; // configuration successful, update current configuration
} bConfiguration = pSetup->wValue & 0xFF;
// configuration successful, update current configuration break;
bConfiguration = pSetup->wValue & 0xFF;
break; case REQ_CLEAR_FEATURE:
case REQ_SET_FEATURE:
case REQ_CLEAR_FEATURE: if (pSetup->wValue == FEA_REMOTE_WAKEUP) {
case REQ_SET_FEATURE: // put DEVICE_REMOTE_WAKEUP code here
if (pSetup->wValue == FEA_REMOTE_WAKEUP) { }
// put DEVICE_REMOTE_WAKEUP code here if (pSetup->wValue == FEA_TEST_MODE) {
} // put TEST_MODE code here
if (pSetup->wValue == FEA_TEST_MODE) { }
// put TEST_MODE code here return FALSE;
}
return FALSE; case REQ_SET_DESCRIPTOR:
DBG("Device req %d not implemented\n", pSetup->bRequest);
case REQ_SET_DESCRIPTOR: return FALSE;
DBG("Device req %d not implemented\n", pSetup->bRequest);
return FALSE; default:
DBG("Illegal device req %d\n", pSetup->bRequest);
default: return FALSE;
DBG("Illegal device req %d\n", pSetup->bRequest); }
return FALSE;
} return TRUE;
}
return TRUE;
}
/**
Local function to handle a standard interface request
/**
Local function to handle a standard interface request @param [in] pSetup The setup packet
@param [in,out] *piLen Pointer to data length
@param [in] pSetup The setup packet @param [in] ppbData Data buffer.
@param [in,out] *piLen Pointer to data length
@param [in] ppbData Data buffer. @return TRUE if the request was handled successfully
*/
@return TRUE if the request was handled successfully static BOOL HandleStdInterfaceReq(TSetupPacket *pSetup, int *piLen, u8 **ppbData)
*/ {
static BOOL HandleStdInterfaceReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData) u8 *pbData = *ppbData;
{
U8 *pbData = *ppbData; switch (pSetup->bRequest) {
switch (pSetup->bRequest) { case REQ_GET_STATUS:
// no bits specified
case REQ_GET_STATUS: pbData[0] = 0;
// no bits specified pbData[1] = 0;
pbData[0] = 0; *piLen = 2;
pbData[1] = 0; break;
*piLen = 2;
break; case REQ_CLEAR_FEATURE:
case REQ_SET_FEATURE:
case REQ_CLEAR_FEATURE: // not defined for interface
case REQ_SET_FEATURE: return FALSE;
// not defined for interface
return FALSE; case REQ_GET_INTERFACE: // TODO use bNumInterfaces
// there is only one interface, return n-1 (= 0)
case REQ_GET_INTERFACE: // TODO use bNumInterfaces pbData[0] = 0;
// there is only one interface, return n-1 (= 0) *piLen = 1;
pbData[0] = 0; break;
*piLen = 1;
break; case REQ_SET_INTERFACE: // TODO use bNumInterfaces
// there is only one interface (= 0)
case REQ_SET_INTERFACE: // TODO use bNumInterfaces if (pSetup->wValue != 0) {
// there is only one interface (= 0) return FALSE;
if (pSetup->wValue != 0) { }
return FALSE; *piLen = 0;
} break;
*piLen = 0;
break; default:
DBG("Illegal interface req %d\n", pSetup->bRequest);
default: return FALSE;
DBG("Illegal interface req %d\n", pSetup->bRequest); }
return FALSE;
} return TRUE;
}
return TRUE;
}
/**
Local function to handle a standard endpoint request
/**
Local function to handle a standard endpoint request @param [in] pSetup The setup packet
@param [in,out] *piLen Pointer to data length
@param [in] pSetup The setup packet @param [in] ppbData Data buffer.
@param [in,out] *piLen Pointer to data length
@param [in] ppbData Data buffer. @return TRUE if the request was handled successfully
*/
@return TRUE if the request was handled successfully static BOOL HandleStdEndPointReq(TSetupPacket *pSetup, int *piLen, u8 **ppbData)
*/ {
static BOOL HandleStdEndPointReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData) u8 *pbData = *ppbData;
{
U8 *pbData = *ppbData; switch (pSetup->bRequest) {
case REQ_GET_STATUS:
switch (pSetup->bRequest) { // bit 0 = endpointed halted or not
case REQ_GET_STATUS: pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
// bit 0 = endpointed halted or not pbData[1] = 0;
pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0; *piLen = 2;
pbData[1] = 0; break;
*piLen = 2;
break; case REQ_CLEAR_FEATURE:
if (pSetup->wValue == FEA_ENDPOINT_HALT) {
case REQ_CLEAR_FEATURE: // clear HALT by unstalling
if (pSetup->wValue == FEA_ENDPOINT_HALT) { USBHwEPStall(pSetup->wIndex, FALSE);
// clear HALT by unstalling break;
USBHwEPStall(pSetup->wIndex, FALSE); }
break; // only ENDPOINT_HALT defined for endpoints
} return FALSE;
// only ENDPOINT_HALT defined for endpoints
return FALSE; case REQ_SET_FEATURE:
if (pSetup->wValue == FEA_ENDPOINT_HALT) {
case REQ_SET_FEATURE: // set HALT by stalling
if (pSetup->wValue == FEA_ENDPOINT_HALT) { USBHwEPStall(pSetup->wIndex, TRUE);
// set HALT by stalling break;
USBHwEPStall(pSetup->wIndex, TRUE); }
break; // only ENDPOINT_HALT defined for endpoints
} return FALSE;
// only ENDPOINT_HALT defined for endpoints
return FALSE; case REQ_SYNCH_FRAME:
DBG("EP req %d not implemented\n", pSetup->bRequest);
case REQ_SYNCH_FRAME: return FALSE;
DBG("EP req %d not implemented\n", pSetup->bRequest);
return FALSE; default:
DBG("Illegal EP req %d\n", pSetup->bRequest);
default: return FALSE;
DBG("Illegal EP req %d\n", pSetup->bRequest); }
return FALSE;
} return TRUE;
}
return TRUE;
}
/**
Default handler for standard ('chapter 9') requests
/**
Default handler for standard ('chapter 9') requests If a custom request handler was installed, this handler is called first.
If a custom request handler was installed, this handler is called first. @param [in] pSetup The setup packet
@param [in,out] *piLen Pointer to data length
@param [in] pSetup The setup packet @param [in] ppbData Data buffer.
@param [in,out] *piLen Pointer to data length
@param [in] ppbData Data buffer. @return TRUE if the request was handled successfully
*/
@return TRUE if the request was handled successfully BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, u8 **ppbData)
*/ {
BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData) // try the custom request handler first
{ if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {
// try the custom request handler first return TRUE;
if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) { }
return TRUE;
} switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData);
switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) { case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData);
case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData); case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData);
case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData); default: return FALSE;
case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData); }
default: return FALSE; }
}
}
/**
Registers a callback for custom device requests
/**
Registers a callback for custom device requests In USBHandleStandardRequest, the custom request handler gets a first
chance at handling the request before it is handed over to the 'chapter 9'
In USBHandleStandardRequest, the custom request handler gets a first request handler.
chance at handling the request before it is handed over to the 'chapter 9'
request handler. This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
request is sent to an interface, which is not covered by the 'chapter 9'
This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR specification.
request is sent to an interface, which is not covered by the 'chapter 9'
specification. @param [in] pfnHandler Callback function pointer
*/
@param [in] pfnHandler Callback function pointer void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)
*/ {
void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler) pfnHandleCustomReq = pfnHandler;
{ }
pfnHandleCustomReq = pfnHandler;
}