USBD1_LPC18xx.c 30 KB

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