123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- /*
- LPCUSB, an USB device driver for LPC microcontrollers
- Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- /*
- This is a very simple custom device (not belonging to a specific USB
- class). It implements primitive read and write in the ARM memory space.
-
- Each transfer is initiated by a control transfer to inform the device
- about the address and size of the following data transfer.
- The data transfer takes place over a bulk endpoint (BULK_IN_EP for
- reads and BULK_OUT_EP for writes).
- This example can be used to measure USB transfer speed.
- */
- #include "type.h"
- #include "usbdebug.h"
- #include "console.h"
- #include "usbapi.h"
- #include "startup.h"
- #define BULK_IN_EP 0x82
- #define BULK_OUT_EP 0x05
- #define MAX_PACKET_SIZE 64
- #define LE_WORD(x) ((x)&0xFF),((x)>>8)
- static const U8 abDescriptors[] = {
- /* Device descriptor */
- 0x12,
- DESC_DEVICE,
- LE_WORD(0x0200), // bcdUSB
- 0xFF, // bDeviceClass
- 0x00, // bDeviceSubClass
- 0x00, // bDeviceProtocol
- MAX_PACKET_SIZE0, // bMaxPacketSize
- LE_WORD(0xFFFF), // idVendor
- LE_WORD(0x0004), // idProduct
- LE_WORD(0x0100), // bcdDevice
- 0x01, // iManufacturer
- 0x02, // iProduct
- 0x03, // iSerialNumber
- 0x01, // bNumConfigurations
- // configuration
- 0x09,
- DESC_CONFIGURATION,
- LE_WORD(0x20), // wTotalLength
- 0x01, // bNumInterfaces
- 0x01, // bConfigurationValue
- 0x00, // iConfiguration
- 0x80, // bmAttributes
- 0x32, // bMaxPower
- // interface
- 0x09,
- DESC_INTERFACE,
- 0x00, // bInterfaceNumber
- 0x00, // bAlternateSetting
- 0x02, // bNumEndPoints
- 0xFF, // bInterfaceClass
- 0x00, // bInterfaceSubClass
- 0x00, // bInterfaceProtocol
- 0x00, // iInterface
- // bulk in
- 0x07,
- DESC_ENDPOINT,
- BULK_IN_EP, // bEndpointAddress
- 0x02, // bmAttributes = BULK
- LE_WORD(MAX_PACKET_SIZE),// wMaxPacketSize
- 0, // bInterval
- // bulk out
- 0x07,
- DESC_ENDPOINT,
- BULK_OUT_EP, // bEndpointAddress
- 0x02, // bmAttributes = BULK
- LE_WORD(MAX_PACKET_SIZE),// wMaxPacketSize
- 0, // bInterval
- // string descriptors
- 0x04,
- DESC_STRING,
- LE_WORD(0x0409),
- // manufacturer string
- 0x0E,
- DESC_STRING,
- 'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,
- // product string
- 0x1A,
- DESC_STRING,
- 'M', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 'A', 0, 'c', 0, 'c', 0, 'e', 0, 's', 0, 's', 0,
- // serial number string
- 0x12,
- DESC_STRING,
- 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'C', 0, '0', 0, 'D', 0, 'E', 0,
-
- // terminator
- 0
- };
- typedef struct {
- U32 dwAddress;
- U32 dwLength;
- } TMemoryCmd;
- static TMemoryCmd MemoryCmd;
- static U8 abVendorReqData[sizeof(TMemoryCmd)];
- static void _HandleBulkIn(U8 bEP, U8 bEPStatus)
- {
- int iChunk;
-
- iChunk = MIN(MAX_PACKET_SIZE, MemoryCmd.dwLength);
- if (iChunk == 0) {
- DBG("_HandleBulkIn done\n");
- return;
- }
-
- // send next part
- USBHwEPWrite(bEP, (U8 *)MemoryCmd.dwAddress, iChunk);
-
- MemoryCmd.dwAddress += iChunk;
- MemoryCmd.dwLength -= iChunk;
- // limit address range to prevent abort
- MemoryCmd.dwAddress &= ~(-512 * 1024);
- }
- static void _HandleBulkOut(U8 bEP, U8 bEPStatus)
- {
- int iChunk;
-
- // get next part
- iChunk = USBHwEPRead(bEP, NULL, 0);
-
- MemoryCmd.dwAddress += iChunk;
- MemoryCmd.dwLength -= iChunk;
- DBG("_HandleBulkOut addr=%X, len=%d\n",MemoryCmd.dwAddress,MemoryCmd.dwLength);
- if (MemoryCmd.dwLength == 0) {
- DBG("_HandleBulkOut done\n");
- }
- }
- /*************************************************************************
- HandleVendorRequest
- ===================
- Handles vendor specific requests
-
- Control transfer fields:
- * request: 0x01 = prepare memory read
- 0x02 = prepare memory write
- * index: ignored
- * value: ignored
- * data: U32 dwAddress
- U32 dwLength
-
- **************************************************************************/
- static BOOL HandleVendorRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
- {
- TMemoryCmd *pCmd;
-
- pCmd = (TMemoryCmd *)*ppbData;
- switch (pSetup->bRequest) {
-
- // prepare read
- case 0x01:
- MemoryCmd = *pCmd;
- DBG("READ: addr=%X, len=%d\n", MemoryCmd.dwAddress, MemoryCmd.dwLength);
- // send initial packet
- _HandleBulkIn(BULK_IN_EP, 0);
- *piLen = 0;
- break;
-
- // prepare write
- case 0x02:
- MemoryCmd = *pCmd;
- DBG("WRITE: addr=%X, len=%d\n", MemoryCmd.dwAddress, MemoryCmd.dwLength);
- *piLen = 0;
- break;
- default:
- DBG("Unhandled class %X\n", pSetup->bRequest);
- return FALSE;
- }
- return TRUE;
- }
- #define BAUD_RATE 57600
- /*************************************************************************
- main
- ====
- **************************************************************************/
- int main(void)
- {
- // PLL and MAM
- Initialize();
- // init DBG
- ConsoleInit(60000000 / (16 * BAUD_RATE));
- DBG("Initialising USB stack\n");
-
- // initialise stack
- USBInit();
-
- // register device descriptors
- USBRegisterDescriptors(abDescriptors);
- // override standard request handler
- USBRegisterRequestHandler(REQTYPE_TYPE_VENDOR, HandleVendorRequest, abVendorReqData);
- // register endpoints
- USBHwRegisterEPIntHandler(BULK_IN_EP, _HandleBulkIn);
- USBHwRegisterEPIntHandler(BULK_OUT_EP, _HandleBulkOut);
- DBG("Starting USB communication\n");
- // connect to bus
- USBHwConnect(TRUE);
- // call USB interrupt handler continuously
- while (1) {
- USBHwISR();
- }
-
- return 0;
- }
|