main_custom.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. LPCUSB, an USB device driver for LPC microcontrollers
  3. Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. */
  16. /*
  17. This is a very simple custom device (not belonging to a specific USB
  18. class). It implements primitive read and write in the ARM memory space.
  19. Each transfer is initiated by a control transfer to inform the device
  20. about the address and size of the following data transfer.
  21. The data transfer takes place over a bulk endpoint (BULK_IN_EP for
  22. reads and BULK_OUT_EP for writes).
  23. This example can be used to measure USB transfer speed.
  24. */
  25. #include "type.h"
  26. #include "usbdebug.h"
  27. #include "console.h"
  28. #include "usbapi.h"
  29. #include "startup.h"
  30. #define BULK_IN_EP 0x82
  31. #define BULK_OUT_EP 0x05
  32. #define MAX_PACKET_SIZE 64
  33. #define LE_WORD(x) ((x)&0xFF),((x)>>8)
  34. static const U8 abDescriptors[] = {
  35. /* Device descriptor */
  36. 0x12,
  37. DESC_DEVICE,
  38. LE_WORD(0x0200), // bcdUSB
  39. 0xFF, // bDeviceClass
  40. 0x00, // bDeviceSubClass
  41. 0x00, // bDeviceProtocol
  42. MAX_PACKET_SIZE0, // bMaxPacketSize
  43. LE_WORD(0xFFFF), // idVendor
  44. LE_WORD(0x0004), // idProduct
  45. LE_WORD(0x0100), // bcdDevice
  46. 0x01, // iManufacturer
  47. 0x02, // iProduct
  48. 0x03, // iSerialNumber
  49. 0x01, // bNumConfigurations
  50. // configuration
  51. 0x09,
  52. DESC_CONFIGURATION,
  53. LE_WORD(0x20), // wTotalLength
  54. 0x01, // bNumInterfaces
  55. 0x01, // bConfigurationValue
  56. 0x00, // iConfiguration
  57. 0x80, // bmAttributes
  58. 0x32, // bMaxPower
  59. // interface
  60. 0x09,
  61. DESC_INTERFACE,
  62. 0x00, // bInterfaceNumber
  63. 0x00, // bAlternateSetting
  64. 0x02, // bNumEndPoints
  65. 0xFF, // bInterfaceClass
  66. 0x00, // bInterfaceSubClass
  67. 0x00, // bInterfaceProtocol
  68. 0x00, // iInterface
  69. // bulk in
  70. 0x07,
  71. DESC_ENDPOINT,
  72. BULK_IN_EP, // bEndpointAddress
  73. 0x02, // bmAttributes = BULK
  74. LE_WORD(MAX_PACKET_SIZE),// wMaxPacketSize
  75. 0, // bInterval
  76. // bulk out
  77. 0x07,
  78. DESC_ENDPOINT,
  79. BULK_OUT_EP, // bEndpointAddress
  80. 0x02, // bmAttributes = BULK
  81. LE_WORD(MAX_PACKET_SIZE),// wMaxPacketSize
  82. 0, // bInterval
  83. // string descriptors
  84. 0x04,
  85. DESC_STRING,
  86. LE_WORD(0x0409),
  87. // manufacturer string
  88. 0x0E,
  89. DESC_STRING,
  90. 'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,
  91. // product string
  92. 0x1A,
  93. DESC_STRING,
  94. 'M', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 'A', 0, 'c', 0, 'c', 0, 'e', 0, 's', 0, 's', 0,
  95. // serial number string
  96. 0x12,
  97. DESC_STRING,
  98. 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'C', 0, '0', 0, 'D', 0, 'E', 0,
  99. // terminator
  100. 0
  101. };
  102. typedef struct {
  103. U32 dwAddress;
  104. U32 dwLength;
  105. } TMemoryCmd;
  106. static TMemoryCmd MemoryCmd;
  107. static U8 abVendorReqData[sizeof(TMemoryCmd)];
  108. static void _HandleBulkIn(U8 bEP, U8 bEPStatus)
  109. {
  110. int iChunk;
  111. iChunk = MIN(MAX_PACKET_SIZE, MemoryCmd.dwLength);
  112. if (iChunk == 0) {
  113. DBG("_HandleBulkIn done\n");
  114. return;
  115. }
  116. // send next part
  117. USBHwEPWrite(bEP, (U8 *)MemoryCmd.dwAddress, iChunk);
  118. MemoryCmd.dwAddress += iChunk;
  119. MemoryCmd.dwLength -= iChunk;
  120. // limit address range to prevent abort
  121. MemoryCmd.dwAddress &= ~(-512 * 1024);
  122. }
  123. static void _HandleBulkOut(U8 bEP, U8 bEPStatus)
  124. {
  125. int iChunk;
  126. // get next part
  127. iChunk = USBHwEPRead(bEP, NULL, 0);
  128. MemoryCmd.dwAddress += iChunk;
  129. MemoryCmd.dwLength -= iChunk;
  130. DBG("_HandleBulkOut addr=%X, len=%d\n",MemoryCmd.dwAddress,MemoryCmd.dwLength);
  131. if (MemoryCmd.dwLength == 0) {
  132. DBG("_HandleBulkOut done\n");
  133. }
  134. }
  135. /*************************************************************************
  136. HandleVendorRequest
  137. ===================
  138. Handles vendor specific requests
  139. Control transfer fields:
  140. * request: 0x01 = prepare memory read
  141. 0x02 = prepare memory write
  142. * index: ignored
  143. * value: ignored
  144. * data: U32 dwAddress
  145. U32 dwLength
  146. **************************************************************************/
  147. static BOOL HandleVendorRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
  148. {
  149. TMemoryCmd *pCmd;
  150. pCmd = (TMemoryCmd *)*ppbData;
  151. switch (pSetup->bRequest) {
  152. // prepare read
  153. case 0x01:
  154. MemoryCmd = *pCmd;
  155. DBG("READ: addr=%X, len=%d\n", MemoryCmd.dwAddress, MemoryCmd.dwLength);
  156. // send initial packet
  157. _HandleBulkIn(BULK_IN_EP, 0);
  158. *piLen = 0;
  159. break;
  160. // prepare write
  161. case 0x02:
  162. MemoryCmd = *pCmd;
  163. DBG("WRITE: addr=%X, len=%d\n", MemoryCmd.dwAddress, MemoryCmd.dwLength);
  164. *piLen = 0;
  165. break;
  166. default:
  167. DBG("Unhandled class %X\n", pSetup->bRequest);
  168. return FALSE;
  169. }
  170. return TRUE;
  171. }
  172. #define BAUD_RATE 57600
  173. /*************************************************************************
  174. main
  175. ====
  176. **************************************************************************/
  177. int main(void)
  178. {
  179. // PLL and MAM
  180. Initialize();
  181. // init DBG
  182. ConsoleInit(60000000 / (16 * BAUD_RATE));
  183. DBG("Initialising USB stack\n");
  184. // initialise stack
  185. USBInit();
  186. // register device descriptors
  187. USBRegisterDescriptors(abDescriptors);
  188. // override standard request handler
  189. USBRegisterRequestHandler(REQTYPE_TYPE_VENDOR, HandleVendorRequest, abVendorReqData);
  190. // register endpoints
  191. USBHwRegisterEPIntHandler(BULK_IN_EP, _HandleBulkIn);
  192. USBHwRegisterEPIntHandler(BULK_OUT_EP, _HandleBulkOut);
  193. DBG("Starting USB communication\n");
  194. // connect to bus
  195. USBHwConnect(TRUE);
  196. // call USB interrupt handler continuously
  197. while (1) {
  198. USBHwISR();
  199. }
  200. return 0;
  201. }