USBD0_LPC18xx.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. /* --------------------------------------------------------------------------
  2. * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * $Date: 02. March 2016
  19. * $Revision: V2.9
  20. *
  21. * Driver: Driver_USBD0
  22. * Configured: via RTE_Device.h configuration file
  23. * Project: USB Device Driver for NXP LPC18xx
  24. * --------------------------------------------------------------------------
  25. * Use the following configuration settings in the middleware component
  26. * to connect to this driver.
  27. *
  28. * Configuration Setting Value
  29. * --------------------- -----
  30. * Connect to hardware via Driver_USBD# = 0
  31. * --------------------------------------------------------------------------
  32. * Defines used for driver configuration (at compile time):
  33. *
  34. * USBD_MAX_ENDPOINT_NUM: defines maximum number of IN/OUT Endpoint pairs
  35. * that driver will support with Control Endpoint 0
  36. * not included, this value impacts driver memory
  37. * requirements
  38. * - default value: 5
  39. * - maximum value: 5
  40. * -------------------------------------------------------------------------- */
  41. /* History:
  42. * Version 2.9
  43. * Removed unnecessary __packed specifier for structures dQH_t and dTD_t
  44. * Version 2.8
  45. * Corrected PowerControl function for conditional Power full (driver must be initialized)
  46. * Version 2.7
  47. * PowerControl for Power OFF and Uninitialize functions made unconditional
  48. * Version 2.6
  49. * Corrected isochronous endpoint configuration
  50. * Corrected transfer procedure
  51. * Version 2.5
  52. * Corrected isochronous transfer functionality
  53. * Version 2.4
  54. * Corrected CLK_M3_USB1_CFG into CLK_M3_USB0_CFG in USBD_PowerControl
  55. * function
  56. * Version 2.3
  57. * Corrected PORTSC1_D_PFSC into USB_PORTSC1_D_PFSC
  58. * Version 2.2
  59. * Corrected return value in USBD_PowerControl function.
  60. * Version 2.1
  61. * Added USB_LPC18xx_USB0.h with register bit definitions
  62. * Pin configuration moved to USB_LPC18xx.c
  63. * Version 2.0
  64. * Updated to 2.00 API
  65. * Version 1.3
  66. * Re-implementation of the driver
  67. * Version 1.2
  68. * Updated USB1 pin configurations
  69. * Version 1.1
  70. * Based on API V1.10 (namespace prefix ARM_ added)
  71. * Version 1.0
  72. * Initial release
  73. */
  74. #include <stdint.h>
  75. #include <string.h>
  76. #include "Driver_USBD.h"
  77. #include "LPC18xx.h"
  78. #include "USB_LPC18xx.h"
  79. #include "RTE_Device.h"
  80. #include "RTE_Components.h"
  81. #if (RTE_USB_USB0 == 0)
  82. #error "USB0 is not enabled in the RTE_Device.h!"
  83. #endif
  84. #ifndef USBD_MAX_ENDPOINT_NUM
  85. #define USBD_MAX_ENDPOINT_NUM 5U
  86. #endif
  87. #if (USBD_MAX_ENDPOINT_NUM > 5)
  88. #error Too many Endpoints, maximum IN/OUT Endpoint pairs that this driver supports is 5 !!!
  89. #endif
  90. extern uint8_t USB0_role;
  91. extern uint8_t USB0_state;
  92. extern void USB0_PinsConfigure (void);
  93. extern void USB0_PinsUnconfigure (void);
  94. // USBD Driver *****************************************************************
  95. #define ARM_USBD_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,9)
  96. // Driver Version
  97. static const ARM_DRIVER_VERSION usbd_driver_version = { ARM_USBD_API_VERSION, ARM_USBD_DRV_VERSION };
  98. // Driver Capabilities
  99. static const ARM_USBD_CAPABILITIES usbd_driver_capabilities = {
  100. 0U, // VBUS Detection
  101. 0U, // Event VBUS On
  102. 0U // Event VBUS Off
  103. };
  104. #define LPC_USBx LPC_USB0
  105. #define ENDPTCTRL(ep_num) (*(volatile uint32_t *)((uint32_t)(&LPC_USBx->ENDPTCTRL0) + 4U * ep_num))
  106. #define EP_NUM(ep_addr) (ep_addr & ARM_USB_ENDPOINT_NUMBER_MASK)
  107. #define EP_DIR(ep_addr) ((ep_addr >> 7) & 1U)
  108. #define EP_SLL(ep_addr) (EP_DIR(ep_addr) * 16U)
  109. #define EP_IDX(ep_addr) ((EP_NUM(ep_addr) * 2U) + ((ep_addr >> 7) & 1U))
  110. #define EP_MSK(ep_addr) (1UL << (EP_NUM(ep_addr) + EP_SLL(ep_addr)))
  111. typedef struct { // USB Device Endpoint Queue Head
  112. uint32_t cap;
  113. uint32_t curr_dTD;
  114. uint32_t next_dTD;
  115. uint32_t dTD_token;
  116. uint32_t buf[5];
  117. uint32_t reserved;
  118. uint32_t setup[2];
  119. // Use reminder of 64 bytes for transfer information
  120. uint8_t *data;
  121. uint32_t num;
  122. uint32_t num_transferred_total;
  123. uint16_t num_transferring;
  124. uint8_t ep_type;
  125. uint8_t ep_active;
  126. } dQH_t;
  127. typedef struct { // USB Device Endpoint Transfer Descriptor
  128. uint32_t next_dTD;
  129. uint32_t dTD_token;
  130. uint32_t buf[5];
  131. uint32_t reserved;
  132. } dTD_t;
  133. static ARM_USBD_SignalDeviceEvent_t SignalDeviceEvent;
  134. static ARM_USBD_SignalEndpointEvent_t SignalEndpointEvent;
  135. static ARM_USBD_STATE usbd_state;
  136. static uint32_t setup_packet[2]; // Setup packet data
  137. static volatile uint8_t setup_received; // Setup packet received
  138. static dQH_t __align(2048) dQH[(USBD_MAX_ENDPOINT_NUM + 1U) * 2U]; // Queue Heads
  139. static dTD_t __align( 32) dTD[(USBD_MAX_ENDPOINT_NUM + 1U) * 2U]; // Transfer Descriptors
  140. // Function prototypes
  141. static int32_t USBD_EndpointConfigure (uint8_t ep_addr, uint8_t ep_type, uint16_t ep_max_packet_size);
  142. // Auxiliary functions
  143. /**
  144. \fn void USBD_HW_EndpointFlush (uint8_t ep_addr)
  145. \brief Flush Endpoint.
  146. */
  147. static void USBD_HW_EndpointFlush (uint8_t ep_addr) {
  148. uint32_t ep_msk;
  149. ep_msk = EP_MSK(ep_addr);
  150. LPC_USBx->ENDPTFLUSH = ep_msk;
  151. while (LPC_USBx->ENDPTFLUSH & ep_msk);
  152. }
  153. /**
  154. \fn void USBD_Reset (void)
  155. \brief Reset USB Endpoint settings and variables.
  156. */
  157. static void USBD_Reset (void) {
  158. uint8_t i;
  159. // Reset global variables
  160. setup_packet[0] = 0U;
  161. setup_packet[1] = 0U;
  162. setup_received = 0U;
  163. memset((void *)&usbd_state, 0, sizeof(usbd_state));
  164. memset((void *)dQH, 0, sizeof(dQH));
  165. memset((void *)dTD, 0, sizeof(dTD));
  166. for (i = 1U; i <= USBD_MAX_ENDPOINT_NUM; i++) {
  167. ENDPTCTRL(i) &= ~(USB_ENDPTCTRL_RXE | USB_ENDPTCTRL_TXE);
  168. }
  169. // Clear interrupts
  170. LPC_USBx->ENDPTNAK = 0xFFFFFFFFUL;
  171. LPC_USBx->ENDPTNAKEN = 0U;
  172. LPC_USBx->USBSTS_D = 0xFFFFFFFFUL;
  173. LPC_USBx->ENDPTSETUPSTAT = LPC_USBx->ENDPTSETUPSTAT;
  174. LPC_USBx->ENDPTCOMPLETE = LPC_USBx->ENDPTCOMPLETE;
  175. while (LPC_USBx->ENDPTPRIME);
  176. // Clear all Primed buffers
  177. LPC_USBx->ENDPTFLUSH = 0xFFFFFFFFUL;
  178. while (LPC_USBx->ENDPTFLUSH);
  179. // Interrupt threshold control: no threshold
  180. LPC_USBx->USBCMD_D &= ~(USB_USBCMD_D_ITC(0xFFUL));
  181. // Default Initialize Control Endpoint 0
  182. if (usbd_state.speed == ARM_USB_SPEED_HIGH) { // For High-speed
  183. USBD_EndpointConfigure (0x00U, ARM_USB_ENDPOINT_CONTROL, 64U);
  184. USBD_EndpointConfigure (0x80U, ARM_USB_ENDPOINT_CONTROL, 64U);
  185. } else { // For Full/Low-speed
  186. USBD_EndpointConfigure (0x00U, ARM_USB_ENDPOINT_CONTROL, 8U);
  187. USBD_EndpointConfigure (0x80U, ARM_USB_ENDPOINT_CONTROL, 8U);
  188. }
  189. // Set start of endpoint list address
  190. LPC_USBx->ENDPOINTLISTADDR = (uint32_t)dQH;
  191. // Setup lockouts off
  192. LPC_USBx->USBMODE_D |= USB_USBMODE_D_SLOM;
  193. }
  194. /**
  195. \fn void USBD_HW_ReadSetupPacket (void)
  196. \brief Read Setup Packet to buffer.
  197. */
  198. static void USBD_HW_ReadSetupPacket (void) {
  199. do {
  200. LPC_USBx->USBCMD_D |= USB_USBCMD_D_SUTW; // Setup trip wire
  201. // Copy Setup Packet Data to buffer
  202. setup_packet[0] = dQH[0].setup[0];
  203. setup_packet[1] = dQH[0].setup[1];
  204. } while (!(LPC_USBx->USBCMD_D & LPC_USBx->USBCMD_D));
  205. LPC_USBx->USBCMD_D &= ~USB_USBCMD_D_SUTW; // Clear Setup trip wire
  206. LPC_USBx->ENDPTSETUPSTAT = 1U; // Clear Setup bit
  207. }
  208. /**
  209. \fn void USBD_HW_EndpointTransfer (uint8_t ep_addr)
  210. \brief Start transfer on Endpoint.
  211. \param[in] ep_addr Endpoint Address
  212. - ep_addr.0..3: Address
  213. - ep_addr.7: Direction
  214. */
  215. static void USBD_HW_EndpointTransfer (uint8_t ep_addr) {
  216. dQH_t *ptr_dqh;
  217. dTD_t *ptr_dtd;
  218. uint8_t *data;
  219. uint32_t ep_msk, num;
  220. uint8_t ep_idx;
  221. ep_idx = EP_IDX(ep_addr);
  222. ep_msk = EP_MSK(ep_addr);
  223. ptr_dqh = &dQH[ep_idx];
  224. ptr_dtd = &dTD[ep_idx];
  225. data = ptr_dqh->data + ptr_dqh->num_transferred_total;
  226. num = ptr_dqh->num - ptr_dqh->num_transferred_total;
  227. if (num > 0x4000U) { num = 0x4000U; } // Maximum transfer length is 16k
  228. while (LPC_USBx->ENDPTSTAT & ep_msk);
  229. memset (ptr_dtd, 0, sizeof(dTD_t));
  230. // Driver does not support linked endpoint descriptors
  231. // Next link pointer is not valid
  232. ptr_dtd->next_dTD = 1U;
  233. // Configure Transfer Descriptor
  234. ptr_dtd->dTD_token |= USB_bTD_TOKEN_TOTAL_BYTES(num) | // Bytes to transfer
  235. USB_bTD_TOKEN_IOC | // Interrupt on complete
  236. USB_bTD_TOKEN_STATUS_ACTIVE ; // Transfer Active
  237. // Set Buffer Addresses
  238. ptr_dtd->buf[0] = (uint32_t)(data );
  239. ptr_dtd->buf[1] = (uint32_t)(data + 0x1000U);
  240. ptr_dtd->buf[2] = (uint32_t)(data + 0x2000U);
  241. ptr_dtd->buf[3] = (uint32_t)(data + 0x3000U);
  242. ptr_dtd->buf[4] = (uint32_t)(data + 0x4000U);
  243. ptr_dqh->dTD_token &= ~USB_bTD_TOKEN_STATUS_MSK; // Clear status
  244. ptr_dqh->next_dTD = (uint32_t)(ptr_dtd); // Save Transfer Descriptor address to Queue Head overlay
  245. ptr_dqh->num_transferring = num;
  246. LPC_USBx->ENDPTPRIME |= ep_msk; // Prime Endpoint -> Start Transfer
  247. }
  248. // USBD Driver functions
  249. /**
  250. \fn ARM_DRIVER_VERSION USBD_GetVersion (void)
  251. \brief Get driver version.
  252. \return \ref ARM_DRIVER_VERSION
  253. */
  254. static ARM_DRIVER_VERSION USBD_GetVersion (void) { return usbd_driver_version; }
  255. /**
  256. \fn ARM_USBD_CAPABILITIES USBD_GetCapabilities (void)
  257. \brief Get driver capabilities.
  258. \return \ref ARM_USBD_CAPABILITIES
  259. */
  260. static ARM_USBD_CAPABILITIES USBD_GetCapabilities (void) { return usbd_driver_capabilities; }
  261. /**
  262. \fn int32_t USBD_Initialize (ARM_USBD_SignalDeviceEvent_t cb_device_event,
  263. ARM_USBD_SignalEndpointEvent_t cb_endpoint_event)
  264. \brief Initialize USB Device Interface.
  265. \param[in] cb_device_event Pointer to \ref ARM_USBD_SignalDeviceEvent
  266. \param[in] cb_endpoint_event Pointer to \ref ARM_USBD_SignalEndpointEvent
  267. \return \ref execution_status
  268. */
  269. static int32_t USBD_Initialize (ARM_USBD_SignalDeviceEvent_t cb_device_event,
  270. ARM_USBD_SignalEndpointEvent_t cb_endpoint_event) {
  271. if ((USB0_state & USBD_DRIVER_INITIALIZED) != 0U) { return ARM_DRIVER_OK; }
  272. SignalDeviceEvent = cb_device_event;
  273. SignalEndpointEvent = cb_endpoint_event;
  274. USB0_role = ARM_USB_ROLE_DEVICE;
  275. USB0_PinsConfigure ();
  276. USB0_state = USBD_DRIVER_INITIALIZED;
  277. return ARM_DRIVER_OK;
  278. }
  279. /**
  280. \fn int32_t USBD_Uninitialize (void)
  281. \brief De-initialize USB Device Interface.
  282. \return \ref execution_status
  283. */
  284. static int32_t USBD_Uninitialize (void) {
  285. USB0_PinsUnconfigure ();
  286. USB0_role = ARM_USB_ROLE_NONE;
  287. USB0_state &= ~USBD_DRIVER_INITIALIZED;
  288. return ARM_DRIVER_OK;
  289. }
  290. /**
  291. \fn int32_t USBD_PowerControl (ARM_POWER_STATE state)
  292. \brief Control USB Device Interface Power.
  293. \param[in] state Power state
  294. \return \ref execution_status
  295. */
  296. static int32_t USBD_PowerControl (ARM_POWER_STATE state) {
  297. switch (state) {
  298. case ARM_POWER_OFF:
  299. NVIC_DisableIRQ (USB0_IRQn); // Disable interrupt
  300. NVIC_ClearPendingIRQ (USB0_IRQn); // Clear pending interrupt
  301. USB0_state &= ~USBD_DRIVER_POWERED; // Clear powered flag
  302. // Reset variables
  303. setup_received = 0U;
  304. memset((void *)&usbd_state, 0, sizeof(usbd_state));
  305. memset((void *)dQH, 0, sizeof(dQH));
  306. memset((void *)dTD, 0, sizeof(dTD));
  307. if ((LPC_CGU->BASE_USB0_CLK & 1U) == 0U) {
  308. LPC_CREG->CREG0 |= (1U << 5); // Disable USB0 PHY
  309. LPC_CCU1->CLK_USB0_CFG &= ~1U; // Disable USB0 Base Clock
  310. while (LPC_CCU1->CLK_USB0_STAT & 1U);
  311. LPC_CCU1->CLK_M3_USB0_CFG &= ~1U; // Disable USB0 Register Interface Clock
  312. while (LPC_CCU1->CLK_M3_USB0_STAT & 1U);
  313. LPC_CGU->BASE_USB0_CLK = 1U; // Disable Base Clock
  314. }
  315. break;
  316. case ARM_POWER_FULL:
  317. if ((USB0_state & USBD_DRIVER_INITIALIZED) == 0U) { return ARM_DRIVER_ERROR; }
  318. if ((USB0_state & USBD_DRIVER_POWERED) != 0U) { return ARM_DRIVER_OK; }
  319. LPC_CGU->BASE_USB0_CLK = (0x01U << 11) | // Auto-block Enable
  320. (0x07U << 24) ; // Clock source: PLL0USB
  321. LPC_CCU1->CLK_M3_USB0_CFG |= 1U; // Enable USB0 Register Interface Clock
  322. while (!(LPC_CCU1->CLK_M3_USB0_STAT & 1U));
  323. LPC_CCU1->CLK_USB0_CFG |= 1U; // Enable USB0 Base Clock
  324. while (!(LPC_CCU1->CLK_USB0_STAT & 1U));
  325. // Reset USB Controller
  326. LPC_USBx->USBCMD_D = USB_USBCMD_D_RST;
  327. while ((LPC_USBx->USBCMD_D & (USB_USBCMD_D_RS | USB_USBCMD_D_RST)) != 0U);
  328. // Force device mode and set Setup lockouts off
  329. LPC_USBx->USBMODE_D = USB_USBMODE_D_CM1_0(2U) | USB_USBMODE_D_SLOM;
  330. LPC_CREG->CREG0 &= ~(1U << 5); // Enable USB0 PHY
  331. USBD_Reset (); // Reset variables and endpoint settings
  332. #if (RTE_USB_USB0_HS_EN)
  333. LPC_USBx->PORTSC1_D &= ~USB_PORTSC1_D_PFSC;
  334. #else
  335. LPC_USBx->PORTSC1_D |= USB_PORTSC1_D_PFSC;
  336. #endif
  337. // Configure OTG Register
  338. LPC_USBx->OTGSC = USB_OTGSC_VD | // VBUS discharge
  339. USB_OTGSC_OT ; // OTG termination
  340. // Enable interrupts
  341. LPC_USBx->USBINTR_D = (USB_USBINTR_D_UE | // USB interrupt enable
  342. USB_USBINTR_D_PCE | // Port change detect interrupt enable
  343. USB_USBINTR_D_SLE | // Suspend interrupt enable
  344. USB_USBINTR_D_URE); // Reset interrupt enable
  345. USB0_state |= USBD_DRIVER_POWERED; // Set powered flag
  346. NVIC_EnableIRQ (USB0_IRQn); // Enable interrupt
  347. break;
  348. default:
  349. return ARM_DRIVER_ERROR_UNSUPPORTED;
  350. }
  351. return ARM_DRIVER_OK;
  352. }
  353. /**
  354. \fn int32_t USBD_DeviceConnect (void)
  355. \brief Connect USB Device.
  356. \return \ref execution_status
  357. */
  358. static int32_t USBD_DeviceConnect (void) {
  359. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  360. LPC_USBx->USBCMD_D |= USB_USBCMD_D_RS; // Attach Device
  361. return ARM_DRIVER_OK;
  362. }
  363. /**
  364. \fn int32_t USBD_DeviceDisconnect (void)
  365. \brief Disconnect USB Device.
  366. \return \ref execution_status
  367. */
  368. static int32_t USBD_DeviceDisconnect (void) {
  369. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  370. LPC_USBx->USBCMD_D &= ~USB_USBCMD_D_RS; // Detach Device
  371. #if (RTE_USB0_IND0_PIN_EN)
  372. LPC_USBx->PORTSC1_D &= ~USB_PORTSC1_D_PIC1_0(1); // Clear indicator LED0
  373. #endif
  374. return ARM_DRIVER_OK;
  375. }
  376. /**
  377. \fn ARM_USBD_STATE USBD_DeviceGetState (void)
  378. \brief Get current USB Device State.
  379. \return Device State \ref ARM_USBD_STATE
  380. */
  381. static ARM_USBD_STATE USBD_DeviceGetState (void) {
  382. ARM_USBD_STATE dev_state = { 0U, 0U, 0U };
  383. uint32_t portsc1_d;
  384. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return dev_state; }
  385. portsc1_d = LPC_USBx->PORTSC1_D;
  386. dev_state = usbd_state;
  387. dev_state.active = ((portsc1_d & USB_PORTSC1_D_CCS) != 0U) &&
  388. ((portsc1_d & USB_USBDSTS_D_SLI) == 0U) ;
  389. return dev_state;
  390. }
  391. /**
  392. \fn int32_t USBD_DeviceRemoteWakeup (void)
  393. \brief Trigger USB Remote Wakeup.
  394. \return \ref execution_status
  395. */
  396. static int32_t USBD_DeviceRemoteWakeup (void) {
  397. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  398. LPC_USBx->PORTSC1_D &= ~USB_PORTSC1_D_PHCD; // Enable PHY Clock
  399. LPC_USBx->PORTSC1_D |= USB_PORTSC1_D_FPR; // Force Port Resume
  400. return ARM_DRIVER_OK;
  401. }
  402. /**
  403. \fn int32_t USBD_DeviceSetAddress (uint8_t dev_addr)
  404. \brief Set USB Device Address.
  405. \param[in] dev_addr Device Address
  406. \return \ref execution_status
  407. */
  408. static int32_t USBD_DeviceSetAddress (uint8_t dev_addr) {
  409. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  410. LPC_USBx->DEVICEADDR = (dev_addr << USB_DEVICEADDR_USBADR_POS) & USB_DEVICEADDR_USBADR_MSK;
  411. LPC_USBx->DEVICEADDR |= USB_DEVICEADDR_USBADRA;
  412. return ARM_DRIVER_OK;
  413. }
  414. /**
  415. \fn int32_t USBD_ReadSetupPacket (uint8_t *setup)
  416. \brief Read setup packet received over Control Endpoint.
  417. \param[out] setup Pointer to buffer for setup packet
  418. \return \ref execution_status
  419. */
  420. static int32_t USBD_ReadSetupPacket (uint8_t *setup) {
  421. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  422. if (setup_received == 0U) { return ARM_DRIVER_ERROR; }
  423. setup_received = 0U;
  424. memcpy(setup, setup_packet, 8);
  425. if (setup_received != 0U) { // If new setup packet was received while this was being read
  426. return ARM_DRIVER_ERROR;
  427. }
  428. return ARM_DRIVER_OK;
  429. }
  430. /**
  431. \fn int32_t USBD_EndpointConfigure (uint8_t ep_addr,
  432. uint8_t ep_type,
  433. uint16_t ep_max_packet_size)
  434. \brief Configure USB Endpoint.
  435. \param[in] ep_addr Endpoint Address
  436. - ep_addr.0..3: Address
  437. - ep_addr.7: Direction
  438. \param[in] ep_type Endpoint Type (ARM_USB_ENDPOINT_xxx)
  439. \param[in] ep_max_packet_size Endpoint Maximum Packet Size
  440. \return \ref execution_status
  441. */
  442. static int32_t USBD_EndpointConfigure (uint8_t ep_addr,
  443. uint8_t ep_type,
  444. uint16_t ep_max_packet_size) {
  445. dQH_t *ptr_dqh;
  446. uint32_t ep_mult;
  447. uint32_t ep_mps;
  448. uint8_t ep_num,ep_sll;
  449. ep_num = EP_NUM(ep_addr);
  450. if (ep_num > USBD_MAX_ENDPOINT_NUM) { return ARM_DRIVER_ERROR; }
  451. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  452. ptr_dqh = &dQH[EP_IDX(ep_addr)];
  453. if (ptr_dqh->ep_active != 0U) { return ARM_DRIVER_ERROR_BUSY; }
  454. ep_num = EP_NUM(ep_addr);
  455. ep_sll = EP_SLL(ep_addr);
  456. ep_mult = (ep_max_packet_size & ARM_USB_ENDPOINT_MICROFRAME_TRANSACTIONS_MASK) >> 11;
  457. ep_mps = ep_max_packet_size & ARM_USB_ENDPOINT_MAX_PACKET_SIZE_MASK;
  458. // Clear Endpoint Queue Head
  459. memset((void *)ptr_dqh, 0, sizeof(dQH_t));
  460. ptr_dqh->ep_type = ep_type;
  461. if (ep_type == ARM_USB_ENDPOINT_ISOCHRONOUS) {
  462. // For isochronous endpoints number of transactions per microframe in high-speed (or frame in full-speed)
  463. // has to be 1 more than additional transactions per microframe for high-speed (or 1 for full-speed)
  464. ep_mult++;
  465. }
  466. if ((ep_mult > 1U) && (usbd_state.speed == ARM_USB_SPEED_FULL)) { ep_mult = 1U; }
  467. ptr_dqh->cap = ((ep_mult << USB_EPQH_CAP_MULT_POS) & USB_EPQH_CAP_MULT_MSK) |
  468. (USB_EPQH_CAP_MAX_PACKET_LEN(ep_mps)) |
  469. (USB_EPQH_CAP_ZLT) |
  470. ((ep_addr == 0U) * USB_EPQH_CAP_IOS);
  471. ptr_dqh->next_dTD = 1U;
  472. ptr_dqh->dTD_token = 0U;
  473. USBD_HW_EndpointFlush(ep_addr);
  474. // Clear Endpoint Control Settings
  475. ENDPTCTRL(ep_num) &= ~((USB_ENDPTCTRL_RXS |
  476. USB_ENDPTCTRL_RXT_MSK |
  477. USB_ENDPTCTRL_RXI |
  478. USB_ENDPTCTRL_RXR |
  479. USB_ENDPTCTRL_RXE )
  480. << ep_sll);
  481. // Set Endpoint Control Settings
  482. ENDPTCTRL(ep_num) |= (USB_ENDPTCTRL_RXT(ep_type) | // Endpoint Type
  483. USB_ENDPTCTRL_RXR | // Data Tggle Rset
  484. USB_ENDPTCTRL_RXE ) // Endpoint Enable
  485. << ep_sll;
  486. return ARM_DRIVER_OK;
  487. }
  488. /**
  489. \fn int32_t USBD_EndpointUnconfigure (uint8_t ep_addr)
  490. \brief Unconfigure USB Endpoint.
  491. \param[in] ep_addr Endpoint Address
  492. - ep_addr.0..3: Address
  493. - ep_addr.7: Direction
  494. \return \ref execution_status
  495. */
  496. static int32_t USBD_EndpointUnconfigure (uint8_t ep_addr) {
  497. dQH_t *ptr_dqh;
  498. dTD_t *ptr_dtd;
  499. uint8_t ep_idx, ep_num, ep_sll;
  500. ep_num = EP_NUM(ep_addr);
  501. if (ep_num > USBD_MAX_ENDPOINT_NUM) { return ARM_DRIVER_ERROR; }
  502. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  503. ep_idx = EP_IDX(ep_addr);
  504. ptr_dqh = &dQH[ep_idx];
  505. if (ptr_dqh->ep_active != 0U) { return ARM_DRIVER_ERROR_BUSY; }
  506. ptr_dtd = &dTD[ep_idx];
  507. ep_sll = EP_SLL(ep_addr);
  508. // Clear Endpoint Control Settings
  509. ENDPTCTRL(ep_num) &= ~((USB_ENDPTCTRL_RXS |
  510. USB_ENDPTCTRL_RXT_MSK |
  511. USB_ENDPTCTRL_RXI |
  512. USB_ENDPTCTRL_RXR |
  513. USB_ENDPTCTRL_RXE )
  514. << ep_sll);
  515. ENDPTCTRL(ep_num) |= (USB_ENDPTCTRL_RXR << ep_sll); // Data toggle reset
  516. // Clear Endpoint Queue Head and Endpoint Transfer Descriptor
  517. memset((void *)ptr_dqh, 0, sizeof(dQH_t));
  518. memset((void *)ptr_dtd, 0, sizeof(dTD_t));
  519. return ARM_DRIVER_OK;
  520. }
  521. /**
  522. \fn int32_t USBD_EndpointStall (uint8_t ep_addr, bool stall)
  523. \brief Set/Clear Stall for USB Endpoint.
  524. \param[in] ep_addr Endpoint Address
  525. - ep_addr.0..3: Address
  526. - ep_addr.7: Direction
  527. \param[in] stall Operation
  528. - \b false Clear
  529. - \b true Set
  530. \return \ref execution_status
  531. */
  532. static int32_t USBD_EndpointStall (uint8_t ep_addr, bool stall) {
  533. dQH_t *ptr_dqh;
  534. uint8_t ep_num, ep_sll;
  535. ep_num = EP_NUM(ep_addr);
  536. if (ep_num > USBD_MAX_ENDPOINT_NUM) { return ARM_DRIVER_ERROR; }
  537. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  538. ptr_dqh = &dQH[EP_IDX(ep_addr)];
  539. if (ptr_dqh->ep_active != 0U) { return ARM_DRIVER_ERROR_BUSY; }
  540. ep_sll = EP_SLL(ep_addr);
  541. if (stall != 0U) { // Set endpoint stall
  542. ENDPTCTRL(ep_num) |= (USB_ENDPTCTRL_RXS << ep_sll);
  543. } else { // Clear endpoint stall
  544. ENDPTCTRL(ep_num) &= ~(USB_ENDPTCTRL_RXS << ep_sll);
  545. ptr_dqh->dTD_token = 0U;
  546. USBD_HW_EndpointFlush(ep_addr);
  547. ENDPTCTRL(ep_num) |= (USB_ENDPTCTRL_RXR << ep_sll); // Data toggle reset
  548. }
  549. return ARM_DRIVER_OK;
  550. }
  551. /**
  552. \fn int32_t USBD_EndpointTransfer (uint8_t ep_addr, uint8_t *data, uint32_t num)
  553. \brief Read data from or Write data to USB Endpoint.
  554. \param[in] ep_addr Endpoint Address
  555. - ep_addr.0..3: Address
  556. - ep_addr.7: Direction
  557. \param[out] data Pointer to buffer for data to read or with data to write
  558. \param[in] num Number of data bytes to transfer
  559. \return \ref execution_status
  560. */
  561. static int32_t USBD_EndpointTransfer (uint8_t ep_addr, uint8_t *data, uint32_t num) {
  562. dQH_t *ptr_dqh;
  563. if (EP_NUM(ep_addr) > USBD_MAX_ENDPOINT_NUM) { return ARM_DRIVER_ERROR; }
  564. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  565. ptr_dqh = &dQH[EP_IDX(ep_addr)];
  566. if (ptr_dqh->ep_active != 0U) { return ARM_DRIVER_ERROR_BUSY; }
  567. ptr_dqh->ep_active = 1U;
  568. ptr_dqh->data = data;
  569. ptr_dqh->num = num;
  570. ptr_dqh->num_transferred_total = 0U;
  571. ptr_dqh->num_transferring = 0U;
  572. USBD_HW_EndpointTransfer(ep_addr); // Start transfer
  573. return ARM_DRIVER_OK;
  574. }
  575. /**
  576. \fn uint32_t USBD_EndpointTransferGetResult (uint8_t ep_addr)
  577. \brief Get result of USB Endpoint transfer.
  578. \param[in] ep_addr Endpoint Address
  579. - ep_addr.0..3: Address
  580. - ep_addr.7: Direction
  581. \return number of successfully transferred data bytes
  582. */
  583. static uint32_t USBD_EndpointTransferGetResult (uint8_t ep_addr) {
  584. if (EP_NUM(ep_addr) > USBD_MAX_ENDPOINT_NUM) { return 0U; }
  585. return (dQH[EP_IDX(ep_addr)].num_transferred_total);
  586. }
  587. /**
  588. \fn int32_t USBD_EndpointTransferAbort (uint8_t ep_addr)
  589. \brief Abort current USB Endpoint transfer.
  590. \param[in] ep_addr Endpoint Address
  591. - ep_addr.0..3: Address
  592. - ep_addr.7: Direction
  593. \return \ref execution_status
  594. */
  595. static int32_t USBD_EndpointTransferAbort (uint8_t ep_addr) {
  596. dQH_t *ptr_dqh;
  597. uint32_t ep_msk;
  598. uint8_t ep_num, ep_sll;
  599. ep_num = EP_NUM(ep_addr);
  600. if (ep_num > USBD_MAX_ENDPOINT_NUM) { return ARM_DRIVER_ERROR; }
  601. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
  602. ptr_dqh = &dQH[EP_IDX(ep_addr)];
  603. ep_msk = EP_MSK(ep_addr);
  604. ep_sll = EP_SLL(ep_addr);
  605. USBD_HW_EndpointFlush(ep_addr);
  606. LPC_USBx->ENDPTCOMPLETE = ep_msk; // Clear Completed Flag
  607. ENDPTCTRL(ep_num) |= (USB_ENDPTCTRL_RXR << ep_sll); // Data toggle reset
  608. ptr_dqh->dTD_token &= ~0xFFU;
  609. ptr_dqh->ep_active = 0U;
  610. return ARM_DRIVER_OK;
  611. }
  612. /**
  613. \fn uint16_t USBD_GetFrameNumber (void)
  614. \brief Get current USB Frame Number.
  615. \return Frame Number
  616. */
  617. static uint16_t USBD_GetFrameNumber (void) {
  618. if ((USB0_state & USBD_DRIVER_POWERED) == 0U) { return 0U; }
  619. return ((LPC_USBx->FRINDEX_D & USB_FRINDEX_D_FRINDEX13_3_MSK) >> USB_FRINDEX_D_FRINDEX13_3_POS);
  620. }
  621. /**
  622. \fn void USBD0_IRQ (void)
  623. \brief USB0 Device Interrupt Routine (IRQ).
  624. */
  625. void USBD0_IRQ (void) {
  626. dQH_t *ptr_dqh;
  627. uint32_t sts, cmpl;
  628. uint16_t ep_mps, num_transferred;
  629. uint8_t ep_num, ep_addr;
  630. sts = LPC_USBx->USBSTS_D & LPC_USBx->USBINTR_D; // Read active interrupts
  631. cmpl = LPC_USBx->ENDPTCOMPLETE; // Read Endpoint completed status
  632. LPC_USBx->USBSTS_D = sts; // Clear interrupts
  633. LPC_USBx->ENDPTCOMPLETE = cmpl; // Clear Endpoint completed status
  634. if ((sts & USB_USBDSTS_D_URI) != 0U) { // Reset interrupt
  635. USBD_Reset();
  636. SignalDeviceEvent(ARM_USBD_EVENT_RESET);
  637. }
  638. if ((sts & USB_USBDSTS_D_SLI) != 0U) { // Suspend interrupt
  639. SignalDeviceEvent(ARM_USBD_EVENT_SUSPEND);
  640. #if (RTE_USB0_IND0_PIN_EN)
  641. LPC_USBx->PORTSC1_D &= ~USB_PORTSC1_D_PIC1_0(1); // Clear indicator LED0
  642. #endif
  643. }
  644. if ((sts & USB_USBDSTS_D_PCI) != 0U) { // Port change detect interrupt
  645. if (((LPC_USBx->PORTSC1_D & USB_PORTSC1_D_PSPD_MSK) >> USB_PORTSC1_D_PSPD_POS) == 2U) {
  646. usbd_state.speed = ARM_USB_SPEED_HIGH;
  647. SignalDeviceEvent(ARM_USBD_EVENT_HIGH_SPEED);
  648. } else {
  649. usbd_state.speed = ARM_USB_SPEED_FULL;
  650. }
  651. #if (RTE_USB0_IND0_PIN_EN)
  652. LPC_USBx->PORTSC1_D |= USB_PORTSC1_D_PIC1_0(1); // Set indicator LED0
  653. #endif
  654. SignalDeviceEvent(ARM_USBD_EVENT_RESUME);
  655. }
  656. if ((sts & USB_USBDSTS_D_UI) != 0U) { // USB interrupt - completed transfer
  657. if ((LPC_USBx->ENDPTSETUPSTAT) != 0U) { // Setup Packet Received
  658. USBD_HW_ReadSetupPacket();
  659. setup_received = 1U;
  660. SignalEndpointEvent(0, ARM_USBD_EVENT_SETUP);
  661. }
  662. if ((cmpl & USB_ENDPTCOMPLETE_ETCE_MSK) != 0U) { // IN Data Sent
  663. for (ep_num = 0U; ep_num <= USBD_MAX_ENDPOINT_NUM; ep_num++) {
  664. if ((cmpl & USB_ENDPTCOMPLETE_ETCE_MSK) & (1U << (ep_num + USB_ENDPTCOMPLETE_ETCE_POS))) {
  665. ep_addr = ep_num | ARM_USB_ENDPOINT_DIRECTION_MASK;
  666. ptr_dqh = &dQH[EP_IDX(ep_addr)];
  667. ptr_dqh->num_transferred_total += ptr_dqh->num_transferring;
  668. // Check if all required IN data was sent
  669. if (ptr_dqh->num == ptr_dqh->num_transferred_total) {
  670. ptr_dqh->ep_active = 0U; // Clear Endpoint busy flag
  671. SignalEndpointEvent(ep_addr, ARM_USBD_EVENT_IN); // Send IN event
  672. } else if (ptr_dqh->ep_active != 0U) {
  673. USBD_HW_EndpointTransfer (ep_addr); // If this was not last transfer, start next
  674. }
  675. }
  676. }
  677. }
  678. if ((cmpl & USB_ENDPTCOMPLETE_ERCE_MSK) != 0U) { // OUT Data Received
  679. for (ep_num = 0U; ep_num <= USBD_MAX_ENDPOINT_NUM; ep_num++) {
  680. if ((cmpl & USB_ENDPTCOMPLETE_ERCE_MSK) & (1 << ep_num)) {
  681. ep_addr = ep_num;
  682. ptr_dqh = &dQH[EP_IDX(ep_addr)];
  683. ep_mps = (ptr_dqh->cap & USB_EPQH_CAP_MAX_PACKET_LEN_MSK) >> USB_EPQH_CAP_MAX_PACKET_LEN_POS;
  684. num_transferred = ptr_dqh->num_transferring -
  685. ((ptr_dqh->dTD_token & USB_bTD_TOKEN_TOTAL_BYTES_MSK) >> USB_bTD_TOKEN_TOTAL_BYTES_POS);
  686. ptr_dqh->num_transferred_total += num_transferred;
  687. // Check if all OUT data was received:
  688. // - data terminated with ZLP or short packet or
  689. // - all required data received
  690. if (((num_transferred % ep_mps) != 0U) || (ptr_dqh->num == ptr_dqh->num_transferred_total)) {
  691. ptr_dqh->ep_active = 0U; // Clear Endpoint busy flag
  692. SignalEndpointEvent(ep_addr, ARM_USBD_EVENT_OUT); // Send OUT event
  693. } else if (ptr_dqh->ep_active != 0U) {
  694. USBD_HW_EndpointTransfer (ep_addr); // If this was not last transfer, start next
  695. }
  696. }
  697. }
  698. }
  699. }
  700. }
  701. ARM_DRIVER_USBD Driver_USBD0 = {
  702. USBD_GetVersion,
  703. USBD_GetCapabilities,
  704. USBD_Initialize,
  705. USBD_Uninitialize,
  706. USBD_PowerControl,
  707. USBD_DeviceConnect,
  708. USBD_DeviceDisconnect,
  709. USBD_DeviceGetState,
  710. USBD_DeviceRemoteWakeup,
  711. USBD_DeviceSetAddress,
  712. USBD_ReadSetupPacket,
  713. USBD_EndpointConfigure,
  714. USBD_EndpointUnconfigure,
  715. USBD_EndpointStall,
  716. USBD_EndpointTransfer,
  717. USBD_EndpointTransferGetResult,
  718. USBD_EndpointTransferAbort,
  719. USBD_GetFrameNumber
  720. };