usbh_hal.c 18 KB

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