usbh_hal.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <string.h>
  9. #include "sdkconfig.h"
  10. #include "hal/usbh_hal.h"
  11. #include "hal/usbh_ll.h"
  12. #include "hal/assert.h"
  13. // ------------------------------------------------ Macros and Types ---------------------------------------------------
  14. // ---------------------- Constants ------------------------
  15. #define BENDPOINTADDRESS_NUM_MSK 0x0F //Endpoint number mask of the bEndpointAddress field of an endpoint descriptor
  16. #define BENDPOINTADDRESS_DIR_MSK 0x80 //Endpoint direction mask of the bEndpointAddress field of an endpoint descriptor
  17. #define CORE_REG_GSNPSID 0x4F54400A
  18. #define CORE_REG_GHWCFG1 0x00000000
  19. #define CORE_REG_GHWCFG2 0x224DD930
  20. #define CORE_REG_GHWCFG3 0x00C804B5
  21. #define CORE_REG_GHWCFG4 0xD3F0A030
  22. // -------------------- Configurable -----------------------
  23. /**
  24. * The following core interrupts will be enabled (listed LSB to MSB). Some of these
  25. * interrupts are enabled later than others.
  26. * - USB_LL_INTR_CORE_PRTINT
  27. * - USB_LL_INTR_CORE_HCHINT
  28. * - USB_LL_INTR_CORE_DISCONNINT
  29. * The following PORT interrupts cannot be masked, listed LSB to MSB
  30. * - USBH_LL_INTR_HPRT_PRTCONNDET
  31. * - USBH_LL_INTR_HPRT_PRTENCHNG
  32. * - USBH_LL_INTR_HPRT_PRTOVRCURRCHNG
  33. */
  34. #define CORE_INTRS_EN_MSK (USB_LL_INTR_CORE_DISCONNINT)
  35. //Interrupts that pertain to core events
  36. #define CORE_EVENTS_INTRS_MSK (USB_LL_INTR_CORE_DISCONNINT | \
  37. USB_LL_INTR_CORE_HCHINT)
  38. //Interrupt that pertain to host port events
  39. #define PORT_EVENTS_INTRS_MSK (USBH_LL_INTR_HPRT_PRTCONNDET | \
  40. USBH_LL_INTR_HPRT_PRTENCHNG | \
  41. USBH_LL_INTR_HPRT_PRTOVRCURRCHNG)
  42. /**
  43. * The following channel interrupt bits are currently checked (in order LSB to MSB)
  44. * - USBH_LL_INTR_CHAN_XFERCOMPL
  45. * - USBH_LL_INTR_CHAN_CHHLTD
  46. * - USBH_LL_INTR_CHAN_STALL
  47. * - USBH_LL_INTR_CHAN_BBLEER
  48. * - USBH_LL_INTR_CHAN_BNAINTR
  49. * - USBH_LL_INTR_CHAN_XCS_XACT_ERR
  50. *
  51. * Note the following points about channel interrupts:
  52. * - Not all bits are unmaskable under scatter/gather
  53. * - Those bits proxy their interrupt through the USBH_LL_INTR_CHAN_CHHLTD bit
  54. * - USBH_LL_INTR_CHAN_XCS_XACT_ERR is always unmasked
  55. * - When USBH_LL_INTR_CHAN_BNAINTR occurs, USBH_LL_INTR_CHAN_CHHLTD will NOT.
  56. * - USBH_LL_INTR_CHAN_AHBERR doesn't actually ever happen on our system (i.e., ESP32-S2, ESP32-S3):
  57. * - If the QTD list's starting address is an invalid address (e.g., NULL), the core will attempt to fetch that
  58. * address for a transfer descriptor and probably gets all zeroes. It will interpret the zero as a bad QTD and
  59. * return a USBH_LL_INTR_CHAN_BNAINTR instead.
  60. * - If the QTD's buffer pointer is an invalid address, the core will attempt to read/write data to/from that
  61. * invalid buffer address with NO INDICATION OF ERROR. The transfer will be acknowledged and treated as
  62. * successful. Bad buffer pointers MUST BE CHECKED FROM HIGHER LAYERS INSTEAD.
  63. */
  64. #define CHAN_INTRS_EN_MSK (USBH_LL_INTR_CHAN_XFERCOMPL | \
  65. USBH_LL_INTR_CHAN_CHHLTD | \
  66. USBH_LL_INTR_CHAN_BNAINTR)
  67. #define CHAN_INTRS_ERROR_MSK (USBH_LL_INTR_CHAN_STALL | \
  68. USBH_LL_INTR_CHAN_BBLEER | \
  69. USBH_LL_INTR_CHAN_BNAINTR | \
  70. USBH_LL_INTR_CHAN_XCS_XACT_ERR)
  71. // -------------------------------------------------- Core (Global) ----------------------------------------------------
  72. static void set_defaults(usbh_hal_context_t *hal)
  73. {
  74. usbh_ll_internal_phy_conf(hal->wrap_dev); //Enable and configure internal PHY
  75. //GAHBCFG register
  76. usb_ll_en_dma_mode(hal->dev);
  77. #ifdef CONFIG_IDF_TARGET_ESP32S2
  78. usb_ll_set_hbstlen(hal->dev, 1); //Use INCR AHB burst. See the ESP32-S2 and later chip ERRATA.
  79. #elif CONFIG_IDF_TARGET_ESP32S3
  80. usb_ll_set_hbstlen(hal->dev, 0); //Do not use USB burst INCR mode for the ESP32-S3, to avoid interference with other peripherals.
  81. #endif
  82. //GUSBCFG register
  83. usb_ll_dis_hnp_cap(hal->dev); //Disable HNP
  84. usb_ll_dis_srp_cap(hal->dev); //Disable SRP
  85. //Enable interruts
  86. usb_ll_dis_intrs(hal->dev, 0xFFFFFFFF); //Mask all interrupts first
  87. usb_ll_en_intrs(hal->dev, CORE_INTRS_EN_MSK); //Unmask global interrupts
  88. usb_ll_intr_read_and_clear(hal->dev); //Clear interrupts
  89. usb_ll_en_global_intr(hal->dev); //Enable interrupt signal
  90. //Enable host mode
  91. usb_ll_set_host_mode(hal->dev);
  92. }
  93. void usbh_hal_init(usbh_hal_context_t *hal)
  94. {
  95. //Check if a peripheral is alive by reading the core ID registers
  96. usbh_dev_t *dev = &USBH;
  97. uint32_t core_id = usb_ll_get_controller_core_id(dev);
  98. HAL_ASSERT(core_id == CORE_REG_GSNPSID);
  99. (void) core_id; //Suppress unused variable warning if asserts are disabled
  100. //Initialize HAL context
  101. memset(hal, 0, sizeof(usbh_hal_context_t));
  102. hal->dev = dev;
  103. hal->wrap_dev = &USB_WRAP;
  104. set_defaults(hal);
  105. }
  106. void usbh_hal_deinit(usbh_hal_context_t *hal)
  107. {
  108. //Disable and clear global interrupt
  109. usb_ll_dis_intrs(hal->dev, 0xFFFFFFFF); //Disable all interrupts
  110. usb_ll_intr_read_and_clear(hal->dev); //Clear interrupts
  111. usb_ll_dis_global_intr(hal->dev); //Disable interrupt signal
  112. hal->dev = NULL;
  113. hal->wrap_dev = NULL;
  114. }
  115. void usbh_hal_core_soft_reset(usbh_hal_context_t *hal)
  116. {
  117. usb_ll_core_soft_reset(hal->dev);
  118. while (usb_ll_check_core_soft_reset(hal->dev)) {
  119. ; //Wait until core reset is done
  120. }
  121. while (!usb_ll_check_ahb_idle(hal->dev)) {
  122. ; //Wait until AHB Master bus is idle before doing any other operations
  123. }
  124. //Set the default bits
  125. set_defaults(hal);
  126. //Clear all the flags and channels
  127. hal->periodic_frame_list = NULL;
  128. hal->flags.val = 0;
  129. hal->channels.num_allocd = 0;
  130. hal->channels.chan_pend_intrs_msk = 0;
  131. memset(hal->channels.hdls, 0, sizeof(usbh_hal_chan_t *) * USBH_HAL_NUM_CHAN);
  132. }
  133. void usbh_hal_set_fifo_size(usbh_hal_context_t *hal, const usbh_hal_fifo_config_t *fifo_config)
  134. {
  135. HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USBH_HAL_FIFO_TOTAL_USABLE_LINES);
  136. //Check that none of the channels are active
  137. for (int i = 0; i < USBH_HAL_NUM_CHAN; i++) {
  138. if (hal->channels.hdls[i] != NULL) {
  139. HAL_ASSERT(!hal->channels.hdls[i]->flags.active);
  140. }
  141. }
  142. //Set the new FIFO lengths
  143. usb_ll_set_rx_fifo_size(hal->dev, fifo_config->rx_fifo_lines);
  144. usb_ll_set_nptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines, fifo_config->nptx_fifo_lines);
  145. usbh_ll_set_ptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines, fifo_config->ptx_fifo_lines);
  146. //Flush the FIFOs
  147. usb_ll_flush_nptx_fifo(hal->dev);
  148. usb_ll_flush_ptx_fifo(hal->dev);
  149. usb_ll_flush_rx_fifo(hal->dev);
  150. hal->flags.fifo_sizes_set = 1;
  151. }
  152. // ---------------------------------------------------- Host Port ------------------------------------------------------
  153. static inline void debounce_lock_enable(usbh_hal_context_t *hal)
  154. {
  155. //Disable the hprt (connection) and disconnection interrupts to prevent repeated triggerings
  156. usb_ll_dis_intrs(hal->dev, USB_LL_INTR_CORE_PRTINT | USB_LL_INTR_CORE_DISCONNINT);
  157. hal->flags.dbnc_lock_enabled = 1;
  158. }
  159. void usbh_hal_port_enable(usbh_hal_context_t *hal)
  160. {
  161. usb_priv_speed_t speed = usbh_ll_hprt_get_speed(hal->dev);
  162. //Host Configuration
  163. usbh_ll_hcfg_set_defaults(hal->dev, speed);
  164. //Configure HFIR
  165. usbh_ll_hfir_set_defaults(hal->dev, speed);
  166. }
  167. // ----------------------------------------------------- Channel -------------------------------------------------------
  168. // ----------------- Channel Allocation --------------------
  169. bool usbh_hal_chan_alloc(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, void *chan_ctx)
  170. {
  171. HAL_ASSERT(hal->flags.fifo_sizes_set); //FIFO sizes should be set befor attempting to allocate a channel
  172. //Attempt to allocate channel
  173. if (hal->channels.num_allocd == USBH_HAL_NUM_CHAN) {
  174. return false; //Out of free channels
  175. }
  176. int chan_idx = -1;
  177. for (int i = 0; i < USBH_HAL_NUM_CHAN; i++) {
  178. if (hal->channels.hdls[i] == NULL) {
  179. hal->channels.hdls[i] = chan_obj;
  180. chan_idx = i;
  181. hal->channels.num_allocd++;
  182. break;
  183. }
  184. }
  185. HAL_ASSERT(chan_idx != -1);
  186. //Initialize channel object
  187. memset(chan_obj, 0, sizeof(usbh_hal_chan_t));
  188. chan_obj->flags.chan_idx = chan_idx;
  189. chan_obj->regs = usbh_ll_get_chan_regs(hal->dev, chan_idx);
  190. chan_obj->chan_ctx = chan_ctx;
  191. //Note: EP characteristics configured separately
  192. //Clean and unmask the channel's interrupt
  193. usbh_ll_chan_intr_read_and_clear(chan_obj->regs); //Clear the interrupt bits for that channel
  194. usbh_ll_haintmsk_en_chan_intr(hal->dev, 1 << chan_obj->flags.chan_idx);
  195. usbh_ll_chan_set_intr_mask(chan_obj->regs, CHAN_INTRS_EN_MSK); //Unmask interrupts for this channel
  196. usbh_ll_chan_set_pid(chan_obj->regs, 0); //Set the initial PID to zero
  197. usbh_ll_chan_hctsiz_init(chan_obj->regs); //Set the non changing parts of the HCTSIZ registers (e.g., do_ping and sched info)
  198. return true;
  199. }
  200. void usbh_hal_chan_free(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj)
  201. {
  202. if (chan_obj->type == USB_PRIV_XFER_TYPE_INTR || chan_obj->type == USB_PRIV_XFER_TYPE_ISOCHRONOUS) {
  203. //Unschedule this channel
  204. for (int i = 0; i < hal->frame_list_len; i++) {
  205. hal->periodic_frame_list[i] &= ~(1 << chan_obj->flags.chan_idx);
  206. }
  207. }
  208. //Can only free a channel when in the disabled state and descriptor list released
  209. HAL_ASSERT(!chan_obj->flags.active);
  210. //Disable channel's interrupt
  211. usbh_ll_haintmsk_dis_chan_intr(hal->dev, 1 << chan_obj->flags.chan_idx);
  212. //Deallocate channel
  213. hal->channels.hdls[chan_obj->flags.chan_idx] = NULL;
  214. hal->channels.num_allocd--;
  215. HAL_ASSERT(hal->channels.num_allocd >= 0);
  216. }
  217. // ---------------- Channel Configuration ------------------
  218. void usbh_hal_chan_set_ep_char(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, usbh_hal_ep_char_t *ep_char)
  219. {
  220. //Cannot change ep_char whilst channel is still active or in error
  221. HAL_ASSERT(!chan_obj->flags.active);
  222. //Set the endpoint characteristics of the pipe
  223. usbh_ll_chan_hcchar_init(chan_obj->regs,
  224. ep_char->dev_addr,
  225. ep_char->bEndpointAddress & BENDPOINTADDRESS_NUM_MSK,
  226. ep_char->mps,
  227. ep_char->type,
  228. ep_char->bEndpointAddress & BENDPOINTADDRESS_DIR_MSK,
  229. ep_char->ls_via_fs_hub);
  230. //Save channel type
  231. chan_obj->type = ep_char->type;
  232. //If this is a periodic endpoint/channel, set its schedule in the frame list
  233. if (ep_char->type == USB_PRIV_XFER_TYPE_ISOCHRONOUS || ep_char->type == USB_PRIV_XFER_TYPE_INTR) {
  234. HAL_ASSERT((int)ep_char->periodic.interval <= (int)hal->frame_list_len); //Interval cannot exceed the length of the frame list
  235. //Find the effective offset in the frame list (in case the phase_offset_frames > interval)
  236. int offset = ep_char->periodic.phase_offset_frames % ep_char->periodic.interval;
  237. //Schedule the channel in the frame list
  238. for (int i = offset; i < hal->frame_list_len; i+= ep_char->periodic.interval) {
  239. hal->periodic_frame_list[i] |= 1 << chan_obj->flags.chan_idx;
  240. }
  241. }
  242. }
  243. // ------------------- Channel Control ---------------------
  244. void usbh_hal_chan_activate(usbh_hal_chan_t *chan_obj, void *xfer_desc_list, int desc_list_len, int start_idx)
  245. {
  246. //Cannot activate a channel that has already been enabled or is pending error handling
  247. HAL_ASSERT(!chan_obj->flags.active);
  248. //Set start address of the QTD list and starting QTD index
  249. usbh_ll_chan_set_dma_addr_non_iso(chan_obj->regs, xfer_desc_list, start_idx);
  250. usbh_ll_chan_set_qtd_list_len(chan_obj->regs, desc_list_len);
  251. usbh_ll_chan_start(chan_obj->regs); //Start the channel
  252. chan_obj->flags.active = 1;
  253. }
  254. bool usbh_hal_chan_request_halt(usbh_hal_chan_t *chan_obj)
  255. {
  256. //Cannot request halt on a channel that is pending error handling
  257. if (usbh_ll_chan_is_active(chan_obj->regs)) {
  258. //If the register indicates that the channel is still active, the active flag must have been previously set
  259. HAL_ASSERT(chan_obj->flags.active);
  260. usbh_ll_chan_halt(chan_obj->regs);
  261. chan_obj->flags.halt_requested = 1;
  262. return false;
  263. } else {
  264. //We just clear the active flag here as it could still be set (if we have a pending channel interrupt)
  265. chan_obj->flags.active = 0;
  266. return true;
  267. }
  268. }
  269. // ------------------------------------------------- Event Handling ----------------------------------------------------
  270. usbh_hal_port_event_t usbh_hal_decode_intr(usbh_hal_context_t *hal)
  271. {
  272. uint32_t intrs_core = usb_ll_intr_read_and_clear(hal->dev); //Read and clear core interrupts
  273. uint32_t intrs_port = 0;
  274. if (intrs_core & USB_LL_INTR_CORE_PRTINT) {
  275. //There are host port interrupts. Read and clear those as well.
  276. intrs_port = usbh_ll_hprt_intr_read_and_clear(hal->dev);
  277. }
  278. //Note: Do not change order of checks. Regressing events (e.g. enable -> disabled, connected -> connected)
  279. //always take precedence. ENABLED < DISABLED < CONN < DISCONN < OVRCUR
  280. usbh_hal_port_event_t event = USBH_HAL_PORT_EVENT_NONE;
  281. //Check if this is a core or port event
  282. if ((intrs_core & CORE_EVENTS_INTRS_MSK) || (intrs_port & PORT_EVENTS_INTRS_MSK)) {
  283. //Do not change the order of the following checks. Some events/interrupts take precedence over others
  284. if (intrs_core & USB_LL_INTR_CORE_DISCONNINT) {
  285. event = USBH_HAL_PORT_EVENT_DISCONN;
  286. debounce_lock_enable(hal);
  287. //Mask the port connection and disconnection interrupts to prevent repeated triggering
  288. } else if (intrs_port & USBH_LL_INTR_HPRT_PRTOVRCURRCHNG) {
  289. //Check if this is an overcurrent or an overcurrent cleared
  290. if (usbh_ll_hprt_get_port_overcur(hal->dev)) {
  291. event = USBH_HAL_PORT_EVENT_OVRCUR;
  292. } else {
  293. event = USBH_HAL_PORT_EVENT_OVRCUR_CLR;
  294. }
  295. } else if (intrs_port & USBH_LL_INTR_HPRT_PRTENCHNG) {
  296. if (usbh_ll_hprt_get_port_en(hal->dev)) { //Host port was enabled
  297. event = USBH_HAL_PORT_EVENT_ENABLED;
  298. } else { //Host port has been disabled
  299. event = USBH_HAL_PORT_EVENT_DISABLED;
  300. }
  301. } else if (intrs_port & USBH_LL_INTR_HPRT_PRTCONNDET && !hal->flags.dbnc_lock_enabled) {
  302. event = USBH_HAL_PORT_EVENT_CONN;
  303. debounce_lock_enable(hal);
  304. }
  305. }
  306. //Port events always take precedence over channel events
  307. if (event == USBH_HAL_PORT_EVENT_NONE && (intrs_core & USB_LL_INTR_CORE_HCHINT)) {
  308. //One or more channels have pending interrupts. Store the mask of those channels
  309. hal->channels.chan_pend_intrs_msk = usbh_ll_get_chan_intrs_msk(hal->dev);
  310. event = USBH_HAL_PORT_EVENT_CHAN;
  311. }
  312. return event;
  313. }
  314. usbh_hal_chan_t *usbh_hal_get_chan_pending_intr(usbh_hal_context_t *hal)
  315. {
  316. int chan_num = __builtin_ffs(hal->channels.chan_pend_intrs_msk);
  317. if (chan_num) {
  318. hal->channels.chan_pend_intrs_msk &= ~(1 << (chan_num - 1)); //Clear the pending bit for that channel
  319. return hal->channels.hdls[chan_num - 1];
  320. } else {
  321. return NULL;
  322. }
  323. }
  324. usbh_hal_chan_event_t usbh_hal_chan_decode_intr(usbh_hal_chan_t *chan_obj)
  325. {
  326. uint32_t chan_intrs = usbh_ll_chan_intr_read_and_clear(chan_obj->regs);
  327. usbh_hal_chan_event_t chan_event;
  328. //Note: We don't assert on (chan_obj->flags.active) here as it could have been already cleared by usbh_hal_chan_request_halt()
  329. if (chan_intrs & CHAN_INTRS_ERROR_MSK) { //Note: Errors are uncommon, so we check against the entire interrupt mask to reduce frequency of entering this call path
  330. HAL_ASSERT(chan_intrs & USBH_LL_INTR_CHAN_CHHLTD); //An error should have halted the channel
  331. //Store the error in hal context
  332. usbh_hal_chan_error_t error;
  333. if (chan_intrs & USBH_LL_INTR_CHAN_STALL) {
  334. error = USBH_HAL_CHAN_ERROR_STALL;
  335. } else if (chan_intrs & USBH_LL_INTR_CHAN_BBLEER) {
  336. error = USBH_HAL_CHAN_ERROR_PKT_BBL;
  337. } else if (chan_intrs & USBH_LL_INTR_CHAN_BNAINTR) {
  338. error = USBH_HAL_CHAN_ERROR_BNA;
  339. } else { //USBH_LL_INTR_CHAN_XCS_XACT_ERR
  340. error = USBH_HAL_CHAN_ERROR_XCS_XACT;
  341. }
  342. //Update flags
  343. chan_obj->error = error;
  344. chan_obj->flags.active = 0;
  345. //Save the error to be handled later
  346. chan_event = USBH_HAL_CHAN_EVENT_ERROR;
  347. } else if (chan_intrs & USBH_LL_INTR_CHAN_CHHLTD) {
  348. if (chan_obj->flags.halt_requested) {
  349. chan_obj->flags.halt_requested = 0;
  350. chan_event = USBH_HAL_CHAN_EVENT_HALT_REQ;
  351. } else {
  352. //Must have been halted due to QTD HOC
  353. chan_event = USBH_HAL_CHAN_EVENT_CPLT;
  354. }
  355. chan_obj->flags.active = 0;
  356. } else if (chan_intrs & USBH_LL_INTR_CHAN_XFERCOMPL) {
  357. /*
  358. A transfer complete interrupt WITHOUT the channel halting only occurs when receiving a short interrupt IN packet
  359. and the underlying QTD does not have the HOC bit set. This signifies the last packet of the Interrupt transfer
  360. as all interrupt packets must MPS sized except the last.
  361. */
  362. //The channel isn't halted yet, so we need to halt it manually to stop the execution of the next QTD/packet
  363. usbh_ll_chan_halt(chan_obj->regs);
  364. /*
  365. After setting the halt bit, this will generate another channel halted interrupt. We treat this interrupt as
  366. a NONE event, then cycle back with the channel halted interrupt to handle the CPLT event.
  367. */
  368. chan_event = USBH_HAL_CHAN_EVENT_NONE;
  369. } else {
  370. abort(); //Should never reach this point
  371. }
  372. return chan_event;
  373. }