PageRenderTime 50ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/cpu/cc2538/usb/usb-arch.c

https://gitlab.com/rdeterre/contiki
C | 1295 lines | 962 code | 173 blank | 160 comment | 169 complexity | fa86bf68ac272a29a95f44f1a542c2e8 MD5 | raw file
  1. /*
  2. * Copyright (c) 2012, Philippe Retornaz
  3. * Copyright (c) 2012, EPFL STI IMT LSRO1 -- Mobots group
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * 3. Neither the name of the copyright holder nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  22. * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  27. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  29. * OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. /**
  32. * \addtogroup cc2538-usb
  33. * @{
  34. *
  35. * \file
  36. * Arch-specific routines for the cc2538 USB controller. Heavily based on
  37. * the cc2530 driver written by Philippe Retornaz
  38. */
  39. #include "contiki.h"
  40. #include "energest.h"
  41. #include "usb-arch.h"
  42. #include "usb-api.h"
  43. #include "dev/usb-regs.h"
  44. #include "dev/nvic.h"
  45. #include "dev/gpio.h"
  46. #include "dev/ioc.h"
  47. #include "dev/udma.h"
  48. #include "sys/clock.h"
  49. #include "lpm.h"
  50. #include "reg.h"
  51. #include "dev/watchdog.h"
  52. #include <stdbool.h>
  53. #include <stdint.h>
  54. /*---------------------------------------------------------------------------*/
  55. #ifdef USB_PULLUP_PORT
  56. #define USB_PULLUP_PORT_BASE GPIO_PORT_TO_BASE(USB_PULLUP_PORT)
  57. #endif
  58. #ifdef USB_PULLUP_PIN
  59. #define USB_PULLUP_PIN_MASK GPIO_PIN_MASK(USB_PULLUP_PIN)
  60. #endif
  61. /*---------------------------------------------------------------------------*/
  62. /* EP max FIFO sizes without double buffering */
  63. #if CTRL_EP_SIZE > 32
  64. #error Control endpoint size too big
  65. #endif
  66. #if USB_EP1_SIZE > 32
  67. #error Endpoint 1 size too big
  68. #endif
  69. #if USB_EP2_SIZE > 64
  70. #error Endpoint 2 size too big
  71. #endif
  72. #if USB_EP3_SIZE > 128
  73. #error Endpoint 3 size too big
  74. #endif
  75. #if USB_EP4_SIZE > 256
  76. #error Endpoint 4 size too big
  77. #endif
  78. #if USB_EP5_SIZE > 512
  79. #error Endpoint 5 size too big
  80. #endif
  81. /*---------------------------------------------------------------------------*/
  82. /* uDMA transfer threshold. Use DMA only for data size higher than this */
  83. #define UDMA_SIZE_THRESHOLD 8
  84. /* uDMA channel control persistent flags */
  85. #define UDMA_TX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \
  86. | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \
  87. | UDMA_CHCTL_SRCINC_8 | UDMA_CHCTL_DSTINC_NONE)
  88. #define UDMA_RX_FLAGS (UDMA_CHCTL_ARBSIZE_128 | UDMA_CHCTL_XFERMODE_AUTO \
  89. | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_DSTSIZE_8 \
  90. | UDMA_CHCTL_SRCINC_NONE | UDMA_CHCTL_DSTINC_8)
  91. /*---------------------------------------------------------------------------*/
  92. static const uint16_t ep_xfer_size[] = {
  93. CTRL_EP_SIZE,
  94. USB_EP1_SIZE,
  95. USB_EP2_SIZE,
  96. USB_EP3_SIZE,
  97. USB_EP4_SIZE,
  98. USB_EP5_SIZE,
  99. };
  100. /*---------------------------------------------------------------------------*/
  101. typedef struct _USBBuffer usb_buffer;
  102. /*---------------------------------------------------------------------------*/
  103. struct usb_endpoint {
  104. uint8_t halted;
  105. uint8_t addr;
  106. uint8_t flags;
  107. usb_buffer *buffer;
  108. struct process *event_process;
  109. unsigned int events;
  110. uint16_t xfer_size;
  111. };
  112. typedef struct usb_endpoint usb_endpoint_t;
  113. /*---------------------------------------------------------------------------*/
  114. #define EP_STATUS_IDLE 0
  115. #define EP_STATUS_RX 1
  116. #define EP_STATUS_TX 2
  117. #define USB_EP_FLAGS_TYPE_MASK 0x03
  118. #define USB_EP_FLAGS_TYPE_BULK 0x00
  119. #define USB_EP_FLAGS_TYPE_CONTROL 0x01
  120. #define USB_EP_FLAGS_TYPE_ISO 0x02
  121. #define USB_EP_FLAGS_TYPE_INTERRUPT 0x03
  122. #define USB_EP_FLAGS_ENABLED 0x04
  123. #define EP_TYPE(ep) ((ep)->flags & USB_EP_FLAGS_TYPE_MASK)
  124. #define IS_EP_TYPE(ep, type) (EP_TYPE(ep) == (type))
  125. #define IS_CONTROL_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_CONTROL)
  126. #define IS_BULK_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_BULK)
  127. #define IS_INTERRUPT_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_INTERRUPT)
  128. #define IS_ISO_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_ISO)
  129. #define USBIIE_INEPxIE(x) (1 << x)
  130. #define USBOIE_OUEPxIE(x) (1 << x)
  131. #define EPxIF(x) (1 << x)
  132. #define USB_READ_BLOCK 0x01
  133. #define USB_WRITE_NOTIFY 0x02
  134. #define USB_READ_NOTIFY 0x02
  135. #define USB_READ_FAIL 0x04
  136. /* Index in endpoint array */
  137. #define EP_INDEX(addr) ((addr) & 0x7f)
  138. /* Get address of endpoint struct */
  139. #define EP_STRUCT(addr) &usb_endpoints[EP_INDEX(addr)];
  140. /* Number of hardware endpoint */
  141. #define EP_HW_NUM(addr) ((addr) & 0x7f)
  142. /*---------------------------------------------------------------------------*/
  143. static usb_endpoint_t usb_endpoints[USB_MAX_ENDPOINTS];
  144. struct process *event_process = 0;
  145. volatile static unsigned int events = 0;
  146. static uint8_t ep0status;
  147. /*---------------------------------------------------------------------------*/
  148. static uint8_t ep0_tx(void);
  149. static uint8_t ep_tx(uint8_t ep_hw);
  150. static void in_ep_interrupt_handler(uint8_t ep_hw);
  151. static void out_ep_interrupt_handler(uint8_t ep_hw);
  152. static void ep0_interrupt_handler(void);
  153. /*---------------------------------------------------------------------------*/
  154. static uint8_t
  155. disable_irq(void)
  156. {
  157. uint8_t enabled = NVIC_IsIRQEnabled(USB_IRQn);
  158. if(enabled) {
  159. NVIC_DisableIRQ(USB_IRQn);
  160. }
  161. return enabled;
  162. }
  163. /*---------------------------------------------------------------------------*/
  164. static void
  165. restore_irq(uint8_t enabled)
  166. {
  167. if(enabled) {
  168. NVIC_EnableIRQ(USB_IRQn);
  169. }
  170. }
  171. /*---------------------------------------------------------------------------*/
  172. static void
  173. notify_process(unsigned int e)
  174. {
  175. events |= e;
  176. if(event_process) {
  177. process_poll(event_process);
  178. }
  179. }
  180. /*---------------------------------------------------------------------------*/
  181. static void
  182. notify_ep_process(usb_endpoint_t *ep, unsigned int e)
  183. {
  184. ep->events |= e;
  185. if(ep->event_process) {
  186. process_poll(ep->event_process);
  187. }
  188. }
  189. /*---------------------------------------------------------------------------*/
  190. void
  191. usb_set_ep_event_process(unsigned char addr, struct process *p)
  192. {
  193. usb_endpoint_t *ep = EP_STRUCT(addr);
  194. ep->event_process = p;
  195. }
  196. /*---------------------------------------------------------------------------*/
  197. void
  198. usb_arch_set_global_event_process(struct process *p)
  199. {
  200. event_process = p;
  201. }
  202. /*---------------------------------------------------------------------------*/
  203. unsigned int
  204. usb_arch_get_global_events(void)
  205. {
  206. uint8_t flag;
  207. volatile unsigned int e;
  208. flag = disable_irq();
  209. e = events;
  210. events = 0;
  211. restore_irq(flag);
  212. return e;
  213. }
  214. /*---------------------------------------------------------------------------*/
  215. unsigned int
  216. usb_get_ep_events(uint8_t addr)
  217. {
  218. volatile unsigned int e;
  219. uint8_t flag;
  220. usb_endpoint_t *ep = EP_STRUCT(addr);
  221. flag = disable_irq();
  222. e = ep->events;
  223. ep->events = 0;
  224. restore_irq(flag);
  225. return e;
  226. }
  227. /*---------------------------------------------------------------------------*/
  228. static void
  229. read_hw_buffer(uint8_t *to, uint8_t hw_ep, unsigned int len)
  230. {
  231. uint32_t fifo_addr = USB_F0 + (hw_ep << 3);
  232. if(USB_ARCH_CONF_DMA && len > UDMA_SIZE_THRESHOLD) {
  233. /* Set the transfer source and destination addresses */
  234. udma_set_channel_src(USB_ARCH_CONF_RX_DMA_CHAN, fifo_addr);
  235. udma_set_channel_dst(USB_ARCH_CONF_RX_DMA_CHAN,
  236. (uint32_t)(to) + len - 1);
  237. /* Configure the control word */
  238. udma_set_channel_control_word(USB_ARCH_CONF_RX_DMA_CHAN,
  239. UDMA_RX_FLAGS | udma_xfer_size(len));
  240. /* Enabled the RF RX uDMA channel */
  241. udma_channel_enable(USB_ARCH_CONF_RX_DMA_CHAN);
  242. /* Trigger the uDMA transfer */
  243. udma_channel_sw_request(USB_ARCH_CONF_RX_DMA_CHAN);
  244. /* Wait for the transfer to complete. */
  245. while(udma_channel_get_mode(USB_ARCH_CONF_RX_DMA_CHAN));
  246. } else {
  247. while(len--) {
  248. *to++ = REG(fifo_addr);
  249. }
  250. }
  251. }
  252. /*---------------------------------------------------------------------------*/
  253. static void
  254. write_hw_buffer(uint8_t hw_ep, uint8_t *from, unsigned int len)
  255. {
  256. uint32_t fifo_addr = USB_F0 + (hw_ep << 3);
  257. if(USB_ARCH_CONF_DMA && len > UDMA_SIZE_THRESHOLD) {
  258. /* Set the transfer source and destination addresses */
  259. udma_set_channel_src(USB_ARCH_CONF_TX_DMA_CHAN,
  260. (uint32_t)(from) + len - 1);
  261. udma_set_channel_dst(USB_ARCH_CONF_TX_DMA_CHAN, fifo_addr);
  262. /* Configure the control word */
  263. udma_set_channel_control_word(USB_ARCH_CONF_TX_DMA_CHAN,
  264. UDMA_TX_FLAGS | udma_xfer_size(len));
  265. /* Enabled the RF RX uDMA channel */
  266. udma_channel_enable(USB_ARCH_CONF_TX_DMA_CHAN);
  267. /* Trigger the uDMA transfer */
  268. udma_channel_sw_request(USB_ARCH_CONF_TX_DMA_CHAN);
  269. /* Wait for the transfer to complete. */
  270. while(udma_channel_get_mode(USB_ARCH_CONF_TX_DMA_CHAN));
  271. } else {
  272. while(len--) {
  273. REG(fifo_addr) = *from++;
  274. }
  275. }
  276. }
  277. /*---------------------------------------------------------------------------*/
  278. static void
  279. reset(void)
  280. {
  281. uint8_t e;
  282. for(e = 0; e < USB_MAX_ENDPOINTS; e++) {
  283. if(usb_endpoints[e].flags & USB_EP_FLAGS_ENABLED) {
  284. usb_buffer *buffer = usb_endpoints[e].buffer;
  285. usb_endpoints[e].flags = 0;
  286. usb_disable_endpoint(e);
  287. while(buffer) {
  288. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  289. buffer = buffer->next;
  290. }
  291. }
  292. }
  293. usb_arch_setup_control_endpoint(0);
  294. }
  295. /*---------------------------------------------------------------------------*/
  296. static bool
  297. permit_pm1(void)
  298. {
  299. /*
  300. * Note: USB Suspend/Resume/Remote Wake-Up are not supported. Once the PLL is
  301. * on, it stays on.
  302. */
  303. return REG(USB_CTRL) == 0;
  304. }
  305. /*---------------------------------------------------------------------------*/
  306. /* Init USB */
  307. void
  308. usb_arch_setup(void)
  309. {
  310. uint8_t i;
  311. lpm_register_peripheral(permit_pm1);
  312. /* Switch on USB PLL & USB module */
  313. REG(USB_CTRL) = USB_CTRL_USB_EN | USB_CTRL_PLL_EN;
  314. /* Wait until USB PLL is stable */
  315. while(!(REG(USB_CTRL) & USB_CTRL_PLL_LOCKED));
  316. /* Enable pull-up on usb port if driven by GPIO */
  317. #if defined(USB_PULLUP_PORT_BASE) && defined(USB_PULLUP_PIN_MASK)
  318. GPIO_SET_OUTPUT(USB_PULLUP_PORT_BASE, USB_PULLUP_PIN_MASK);
  319. GPIO_SET_PIN(USB_PULLUP_PORT_BASE, USB_PULLUP_PIN_MASK);
  320. #endif
  321. for(i = 0; i < USB_MAX_ENDPOINTS; i++) {
  322. usb_endpoints[i].flags = 0;
  323. usb_endpoints[i].event_process = 0;
  324. }
  325. reset();
  326. /* Disable all EP interrupts, EP0 interrupt will be enabled later */
  327. REG(USB_IIE) = 0;
  328. REG(USB_OIE) = 0;
  329. /* Initialise the USB control structures */
  330. if(USB_ARCH_CONF_DMA) {
  331. /* Disable peripheral triggers for our channels */
  332. udma_channel_mask_set(USB_ARCH_CONF_RX_DMA_CHAN);
  333. udma_channel_mask_set(USB_ARCH_CONF_TX_DMA_CHAN);
  334. }
  335. NVIC_EnableIRQ(USB_IRQn);
  336. }
  337. /*---------------------------------------------------------------------------*/
  338. void
  339. usb_submit_recv_buffer(uint8_t addr, usb_buffer *buffer)
  340. {
  341. usb_buffer **tailp;
  342. uint8_t flag;
  343. usb_endpoint_t *ep = EP_STRUCT(addr);
  344. if(!(ep->flags & USB_EP_FLAGS_ENABLED)) {
  345. return;
  346. }
  347. if(buffer->data == NULL && EP_HW_NUM(addr) == 0) {
  348. if(buffer->flags & USB_BUFFER_NOTIFY) {
  349. notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
  350. }
  351. return;
  352. }
  353. flag = disable_irq();
  354. tailp = &ep->buffer;
  355. while(*tailp) {
  356. tailp = &(*tailp)->next;
  357. }
  358. *tailp = buffer;
  359. while(buffer) {
  360. buffer->flags |= USB_BUFFER_SUBMITTED;
  361. buffer = buffer->next;
  362. }
  363. REG(USB_INDEX) = EP_HW_NUM(addr);
  364. if(!EP_HW_NUM(ep->addr)) {
  365. if(REG(USB_CS0) & USB_CS0_OUTPKT_RDY) {
  366. ep0_interrupt_handler();
  367. }
  368. } else {
  369. if(REG(USB_CSOL) & USB_CSOL_OUTPKT_RDY) {
  370. out_ep_interrupt_handler(EP_HW_NUM(ep->addr));
  371. }
  372. }
  373. restore_irq(flag);
  374. }
  375. /*---------------------------------------------------------------------------*/
  376. void
  377. usb_submit_xmit_buffer(uint8_t addr, usb_buffer *buffer)
  378. {
  379. usb_buffer **tailp;
  380. uint8_t flag;
  381. uint8_t res;
  382. usb_endpoint_t *ep = EP_STRUCT(addr);
  383. if(!(ep->flags & USB_EP_FLAGS_ENABLED)) {
  384. return;
  385. }
  386. flag = disable_irq();
  387. if(EP_HW_NUM(addr) == 0) {
  388. if(buffer->data == NULL) {
  389. /* We are asked to send a STATUS packet.
  390. * But the USB hardware will do this automatically
  391. * as soon as we release the HW FIFO. */
  392. REG(USB_INDEX) = 0;
  393. REG(USB_CS0) = USB_CS0_CLR_OUTPKT_RDY | USB_CS0_DATA_END;
  394. notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
  395. restore_irq(flag);
  396. return;
  397. } else {
  398. /* Release the HW FIFO */
  399. REG(USB_INDEX) = 0;
  400. REG(USB_CS0) = USB_CS0_CLR_OUTPKT_RDY;
  401. }
  402. }
  403. tailp = &ep->buffer;
  404. while(*tailp) {
  405. tailp = &(*tailp)->next;
  406. }
  407. *tailp = buffer;
  408. while(buffer) {
  409. buffer->flags |= USB_BUFFER_SUBMITTED | USB_BUFFER_IN;
  410. buffer = buffer->next;
  411. }
  412. REG(USB_INDEX) = EP_HW_NUM(ep->addr);
  413. if(EP_HW_NUM(ep->addr)) {
  414. res = ep_tx(EP_HW_NUM(ep->addr));
  415. } else {
  416. res = ep0_tx();
  417. }
  418. restore_irq(flag);
  419. if(res & USB_WRITE_NOTIFY) {
  420. notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
  421. }
  422. }
  423. /*---------------------------------------------------------------------------*/
  424. static void
  425. ep0_setup(void)
  426. {
  427. REG(USB_IIE) |= USB_IIE_EP0IE;
  428. }
  429. /*---------------------------------------------------------------------------*/
  430. static void
  431. in_ep_setup(uint8_t addr)
  432. {
  433. uint8_t ei = EP_HW_NUM(addr);
  434. usb_endpoint_t *ep = EP_STRUCT(addr);
  435. /* Enable IN EP interrupt */
  436. REG(USB_IIE) |= USBIIE_INEPxIE(ei);
  437. /* Set internal FIFO size */
  438. REG(USB_MAXI) = ep->xfer_size / 8;
  439. if(IS_ISO_EP(ep)) {
  440. REG(USB_CSIH) |= USB_CSOH_ISO;
  441. } else {
  442. REG(USB_CSIH) &= ~USB_CSOH_ISO;
  443. }
  444. }
  445. /*---------------------------------------------------------------------------*/
  446. static void
  447. out_ep_setup(uint8_t addr)
  448. {
  449. uint8_t ei = EP_HW_NUM(addr);
  450. usb_endpoint_t *ep = EP_STRUCT(addr);
  451. /* Enable OUT EP interrupt */
  452. REG(USB_OIE) |= USBOIE_OUEPxIE(ei);
  453. /* Set internal FIFO size */
  454. REG(USB_MAXO) = ep->xfer_size / 8;
  455. if(IS_ISO_EP(ep)) {
  456. REG(USB_CSOH) |= USB_CSOH_ISO;
  457. } else {
  458. REG(USB_CSOH) &= ~USB_CSOH_ISO;
  459. }
  460. }
  461. /*---------------------------------------------------------------------------*/
  462. static void
  463. ep_setup(uint8_t addr)
  464. {
  465. uint8_t ei = EP_HW_NUM(addr);
  466. uint8_t flag;
  467. usb_endpoint_t *ep = EP_STRUCT(addr);
  468. ep->halted = 0;
  469. ep->flags |= USB_EP_FLAGS_ENABLED;
  470. ep->buffer = 0;
  471. ep->addr = addr;
  472. ep->events = 0;
  473. ep->xfer_size = ep_xfer_size[ei];
  474. flag = disable_irq();
  475. /* Select endpoint register */
  476. REG(USB_INDEX) = ei;
  477. /* EP0 requires special handing */
  478. if(ei == 0) {
  479. ep0_setup();
  480. } else {
  481. if(addr & 0x80) {
  482. in_ep_setup(addr);
  483. } else {
  484. out_ep_setup(addr);
  485. }
  486. }
  487. restore_irq(flag);
  488. }
  489. /*---------------------------------------------------------------------------*/
  490. void
  491. usb_arch_setup_iso_endpoint(uint8_t addr)
  492. {
  493. usb_endpoint_t *ep = EP_STRUCT(addr);
  494. ep->flags = USB_EP_FLAGS_TYPE_ISO;
  495. ep_setup(addr);
  496. }
  497. /*---------------------------------------------------------------------------*/
  498. void
  499. usb_arch_setup_control_endpoint(uint8_t addr)
  500. {
  501. usb_endpoint_t *ep = EP_STRUCT(addr);
  502. ep->flags = USB_EP_FLAGS_TYPE_CONTROL;
  503. ep_setup(addr);
  504. }
  505. /*---------------------------------------------------------------------------*/
  506. void
  507. usb_arch_setup_bulk_endpoint(uint8_t addr)
  508. {
  509. usb_endpoint_t *ep = EP_STRUCT(addr);
  510. ep->flags = USB_EP_FLAGS_TYPE_BULK;
  511. ep_setup(addr);
  512. }
  513. /*---------------------------------------------------------------------------*/
  514. void
  515. usb_arch_setup_interrupt_endpoint(uint8_t addr)
  516. {
  517. usb_endpoint_t *ep = EP_STRUCT(addr);
  518. ep->flags = USB_EP_FLAGS_TYPE_INTERRUPT;
  519. ep_setup(addr);
  520. }
  521. /*---------------------------------------------------------------------------*/
  522. static void
  523. ep0_dis(void)
  524. {
  525. REG(USB_IIE) &= ~USB_IIE_EP0IE;
  526. /* Clear any pending status flags */
  527. REG(USB_CS0) = 0xC0;
  528. }
  529. /*---------------------------------------------------------------------------*/
  530. static void
  531. in_ep_dis(uint8_t addr)
  532. {
  533. REG(USB_MAXI) = 0;
  534. REG(USB_IIE) &= ~USBIIE_INEPxIE(EP_HW_NUM(addr));
  535. /* Flush pending */
  536. REG(USB_CSIL) = USB_CSIL_FLUSH_PACKET;
  537. }
  538. /*---------------------------------------------------------------------------*/
  539. static void
  540. out_ep_dis(uint8_t addr)
  541. {
  542. REG(USB_MAXO) = 0;
  543. REG(USB_OIE) &= ~USBOIE_OUEPxIE(EP_HW_NUM(addr));
  544. /* Flush pending */
  545. REG(USB_CSOL) = USB_CSIL_FLUSH_PACKET;
  546. }
  547. /*---------------------------------------------------------------------------*/
  548. void
  549. usb_arch_disable_endpoint(uint8_t addr)
  550. {
  551. uint8_t ei = EP_HW_NUM(addr);
  552. uint8_t flag;
  553. usb_endpoint_t *ep = EP_STRUCT(addr);
  554. ep->flags &= ~USB_EP_FLAGS_ENABLED;
  555. flag = disable_irq();
  556. REG(USB_INDEX) = ei;
  557. if(ei == 0) {
  558. ep0_dis();
  559. } else {
  560. if(addr & 0x80) {
  561. in_ep_dis(addr);
  562. } else {
  563. out_ep_dis(addr);
  564. }
  565. }
  566. restore_irq(flag);
  567. }
  568. /*---------------------------------------------------------------------------*/
  569. void
  570. usb_arch_discard_all_buffers(uint8_t addr)
  571. {
  572. usb_buffer *buffer;
  573. uint8_t flag;
  574. volatile usb_endpoint_t *ep = EP_STRUCT(addr);
  575. flag = disable_irq();
  576. buffer = ep->buffer;
  577. ep->buffer = NULL;
  578. restore_irq(flag);
  579. while(buffer) {
  580. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  581. buffer = buffer->next;
  582. }
  583. }
  584. /*---------------------------------------------------------------------------*/
  585. static void
  586. set_stall(uint8_t addr, uint8_t stall)
  587. {
  588. uint8_t ei = EP_HW_NUM(addr);
  589. REG(USB_INDEX) = ei;
  590. if(ei == 0) {
  591. /* Stall is automatically deasserted on EP0 */
  592. if(stall) {
  593. ep0status = EP_STATUS_IDLE;
  594. REG(USB_CS0) |= USB_CS0_SEND_STALL | USB_CS0_OUTPKT_RDY;
  595. }
  596. } else {
  597. if(addr & 0x80) {
  598. if(stall) {
  599. REG(USB_CSIL) |= USB_CSIL_SEND_STALL;
  600. } else {
  601. REG(USB_CSIL) &= ~USB_CSIL_SEND_STALL;
  602. }
  603. } else {
  604. if(stall) {
  605. REG(USB_CSOL) |= USB_CSOL_SEND_STALL;
  606. } else {
  607. REG(USB_CSOL) &= ~USB_CSOL_SEND_STALL;
  608. }
  609. }
  610. }
  611. }
  612. /*---------------------------------------------------------------------------*/
  613. void
  614. usb_arch_control_stall(uint8_t addr)
  615. {
  616. uint8_t ei = EP_HW_NUM(addr);
  617. uint8_t flag;
  618. if(ei > USB_MAX_ENDPOINTS) {
  619. return;
  620. }
  621. flag = disable_irq();
  622. set_stall(addr, 1);
  623. restore_irq(flag);
  624. }
  625. /*---------------------------------------------------------------------------*/
  626. void
  627. usb_arch_halt_endpoint(uint8_t addr, int halt)
  628. {
  629. uint8_t ei = EP_HW_NUM(addr);
  630. uint8_t flag;
  631. usb_endpoint_t *ep = EP_STRUCT(addr);
  632. if(ei > USB_MAX_ENDPOINTS) {
  633. return;
  634. }
  635. if(!(ep->flags & USB_EP_FLAGS_ENABLED)) {
  636. return;
  637. }
  638. flag = disable_irq();
  639. if(halt) {
  640. ep->halted = 0x1;
  641. set_stall(addr, 1);
  642. } else {
  643. ep->halted = 0;
  644. set_stall(addr, 0);
  645. if(ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
  646. ep->buffer->flags &= ~USB_BUFFER_SUBMITTED;
  647. if(ep->buffer->flags & USB_BUFFER_NOTIFY) {
  648. notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
  649. }
  650. ep->buffer = ep->buffer->next;
  651. }
  652. if(ei) {
  653. out_ep_interrupt_handler(EP_HW_NUM(addr));
  654. }
  655. }
  656. restore_irq(flag);
  657. }
  658. /*---------------------------------------------------------------------------*/
  659. void
  660. usb_arch_set_configuration(uint8_t usb_configuration_value)
  661. {
  662. return;
  663. }
  664. /*---------------------------------------------------------------------------*/
  665. uint16_t
  666. usb_arch_get_ep_status(uint8_t addr)
  667. {
  668. uint8_t ei = EP_INDEX(addr);
  669. usb_endpoint_t *ep = EP_STRUCT(addr);
  670. if(ei > USB_MAX_ENDPOINTS) {
  671. return 0;
  672. }
  673. return ep->halted;
  674. }
  675. /*---------------------------------------------------------------------------*/
  676. void
  677. usb_arch_set_address(uint8_t addr)
  678. {
  679. REG(USB_ADDR) = addr;
  680. }
  681. /*---------------------------------------------------------------------------*/
  682. int
  683. usb_arch_send_pending(uint8_t addr)
  684. {
  685. uint8_t flag;
  686. uint8_t ret;
  687. uint8_t ei = EP_INDEX(addr);
  688. flag = disable_irq();
  689. REG(USB_INDEX) = ei;
  690. if(ei == 0) {
  691. ret = REG(USB_CS0) & USB_CS0_INPKT_RDY;
  692. } else {
  693. ret = REG(USB_CSIL) & USB_CSIL_INPKT_RDY;
  694. }
  695. restore_irq(flag);
  696. return ret;
  697. }
  698. /*---------------------------------------------------------------------------*/
  699. static unsigned int
  700. get_receive_capacity(usb_buffer *buffer)
  701. {
  702. unsigned int capacity = 0;
  703. while(buffer &&
  704. !(buffer->flags & (USB_BUFFER_IN | USB_BUFFER_SETUP | USB_BUFFER_HALT))) {
  705. capacity += buffer->left;
  706. buffer = buffer->next;
  707. }
  708. return capacity;
  709. }
  710. /*---------------------------------------------------------------------------*/
  711. static usb_buffer *
  712. skip_buffers_until(usb_buffer *buffer, unsigned int mask, unsigned int flags,
  713. uint8_t *resp)
  714. {
  715. while(buffer && !((buffer->flags & mask) == flags)) {
  716. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  717. buffer->flags |= USB_BUFFER_FAILED;
  718. if(buffer->flags & USB_BUFFER_NOTIFY) {
  719. *resp |= USB_READ_NOTIFY;
  720. }
  721. buffer = buffer->next;
  722. }
  723. return buffer;
  724. }
  725. /*---------------------------------------------------------------------------*/
  726. static uint8_t
  727. fill_buffers(usb_buffer *buffer, uint8_t hw_ep, unsigned int len,
  728. uint8_t short_packet)
  729. {
  730. unsigned int t;
  731. uint8_t res = 0;
  732. do {
  733. if(buffer->left < len) {
  734. t = buffer->left;
  735. } else {
  736. t = len;
  737. }
  738. len -= t;
  739. buffer->left -= t;
  740. read_hw_buffer(buffer->data, hw_ep, t);
  741. buffer->data += t;
  742. if(len == 0) {
  743. break;
  744. }
  745. buffer->flags &= ~(USB_BUFFER_SUBMITTED | USB_BUFFER_SHORT_PACKET);
  746. if(buffer->flags & USB_BUFFER_NOTIFY) {
  747. res |= USB_READ_NOTIFY;
  748. }
  749. buffer = buffer->next;
  750. } while(1);
  751. if(short_packet) {
  752. buffer->flags |= USB_BUFFER_SHORT_PACKET;
  753. }
  754. if((buffer->left == 0) || (buffer->flags & USB_BUFFER_PACKET_END)) {
  755. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  756. if(buffer->flags & USB_BUFFER_NOTIFY) {
  757. res |= USB_READ_NOTIFY;
  758. }
  759. buffer = buffer->next;
  760. } else {
  761. if(short_packet) {
  762. if(buffer->left && !(buffer->flags & USB_BUFFER_SHORT_END)) {
  763. buffer->flags |= USB_BUFFER_FAILED;
  764. res |= USB_READ_FAIL;
  765. }
  766. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  767. if(buffer->flags & USB_BUFFER_NOTIFY) {
  768. res |= USB_READ_NOTIFY;
  769. }
  770. buffer = buffer->next;
  771. }
  772. }
  773. usb_endpoints[hw_ep].buffer = buffer;
  774. return res;
  775. }
  776. /*---------------------------------------------------------------------------*/
  777. static uint8_t
  778. ep0_get_setup_pkt(void)
  779. {
  780. uint8_t res = 0;
  781. usb_buffer *buffer =
  782. skip_buffers_until(usb_endpoints[0].buffer, USB_BUFFER_SETUP,
  783. USB_BUFFER_SETUP, &res);
  784. usb_endpoints[0].buffer = buffer;
  785. if(!buffer || buffer->left < 8) {
  786. return USB_READ_BLOCK;
  787. }
  788. read_hw_buffer(buffer->data, 0, 8);
  789. buffer->left -= 8;
  790. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  791. if(buffer->flags & USB_BUFFER_NOTIFY) {
  792. res |= USB_READ_NOTIFY;
  793. }
  794. if(buffer->data[6] || buffer->data[7]) {
  795. REG(USB_CS0) |= USB_CS0_CLR_OUTPKT_RDY;
  796. ep0status = buffer->data[0] & 0x80 ? EP_STATUS_TX : EP_STATUS_RX;
  797. }
  798. buffer->data += 8;
  799. usb_endpoints[0].buffer = buffer->next;
  800. return res;
  801. }
  802. /*---------------------------------------------------------------------------*/
  803. static uint8_t
  804. ep0_get_data_pkt(void)
  805. {
  806. uint8_t res = 0;
  807. uint8_t short_packet = 0;
  808. usb_buffer *buffer = usb_endpoints[0].buffer;
  809. uint8_t len = REG(USB_CNT0);
  810. if(!buffer) {
  811. return USB_READ_BLOCK;
  812. }
  813. if(buffer->flags & (USB_BUFFER_SETUP | USB_BUFFER_IN)) {
  814. buffer->flags |= USB_BUFFER_FAILED;
  815. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  816. if(buffer->flags & USB_BUFFER_NOTIFY) {
  817. res |= USB_READ_NOTIFY;
  818. }
  819. /* Flush the fifo */
  820. while(len--) {
  821. REG(USB_F0);
  822. }
  823. usb_endpoints[0].buffer = buffer->next;
  824. /* Force data stage end */
  825. REG(USB_CS0) |= USB_CS0_CLR_OUTPKT_RDY | USB_CS0_DATA_END;
  826. ep0status = EP_STATUS_IDLE;
  827. return res;
  828. }
  829. if(get_receive_capacity(buffer) < len) {
  830. /* Wait until we queue more buffers */
  831. return USB_READ_BLOCK;
  832. }
  833. if(len < usb_endpoints[0].xfer_size) {
  834. short_packet = 1;
  835. }
  836. res = fill_buffers(buffer, 0, len, short_packet);
  837. if(short_packet) {
  838. /* The usb-core will send a status packet, we will release the fifo at this stage */
  839. ep0status = EP_STATUS_IDLE;
  840. } else {
  841. REG(USB_CS0) |= USB_CS0_CLR_OUTPKT_RDY;
  842. }
  843. return res;
  844. }
  845. /*---------------------------------------------------------------------------*/
  846. static uint8_t
  847. ep0_tx(void)
  848. {
  849. usb_buffer *buffer = usb_endpoints[0].buffer;
  850. unsigned int len = usb_endpoints[0].xfer_size;
  851. uint8_t data_end = 0;
  852. uint8_t res = 0;
  853. /* If TX Fifo still busy or ep0 not in TX data stage don't do anything */
  854. if((REG(USB_CS0) & USB_CS0_INPKT_RDY) || (ep0status != EP_STATUS_TX)) {
  855. return 0;
  856. }
  857. if(!buffer) {
  858. return 0;
  859. }
  860. if(!(buffer->flags & USB_BUFFER_IN)) {
  861. /* We should TX but queued buffer is in RX */
  862. return 0;
  863. }
  864. while(buffer) {
  865. unsigned int copy;
  866. if(buffer->left < len) {
  867. copy = buffer->left;
  868. } else {
  869. copy = len;
  870. }
  871. len -= copy;
  872. buffer->left -= copy;
  873. write_hw_buffer(0, buffer->data, copy);
  874. buffer->data += copy;
  875. if(buffer->left == 0) {
  876. if(buffer->flags & USB_BUFFER_SHORT_END) {
  877. if(len == 0) {
  878. break; // We keep the buffer in queue so we will send a ZLP next time.
  879. } else {
  880. data_end = 1;
  881. len = 0; // Stop looking for more data to send
  882. }
  883. }
  884. buffer->flags &= ~USB_BUFFER_SUBMITTED;
  885. if(buffer->flags & USB_BUFFER_NOTIFY) {
  886. res |= USB_WRITE_NOTIFY;
  887. }
  888. buffer = buffer->next;
  889. }
  890. if(len == 0) {
  891. break; // FIFO is full, send packet.
  892. }
  893. }
  894. if(len) {
  895. data_end = 1;
  896. }
  897. usb_endpoints[0].buffer = buffer;
  898. /*
  899. * Workaround the fact that the usb controller do not like to have DATA_END
  900. * set after INPKT_RDY for the last packet. Thus if no more is in the queue
  901. * set DATA_END
  902. */
  903. if(data_end || !buffer) {
  904. ep0status = EP_STATUS_IDLE;
  905. REG(USB_CS0) |= USB_CS0_INPKT_RDY | USB_CS0_DATA_END;
  906. } else {
  907. REG(USB_CS0) |= USB_CS0_INPKT_RDY;
  908. }
  909. return res;
  910. }
  911. /*---------------------------------------------------------------------------*/
  912. static void
  913. ep0_interrupt_handler(void)
  914. {
  915. uint8_t cs0;
  916. uint8_t res;
  917. REG(USB_INDEX) = 0;
  918. cs0 = REG(USB_CS0);
  919. if(cs0 & USB_CS0_SENT_STALL) {
  920. /* Ack the stall */
  921. REG(USB_CS0) = 0;
  922. ep0status = EP_STATUS_IDLE;
  923. }
  924. if(cs0 & USB_CS0_SETUP_END) {
  925. /* Clear it */
  926. REG(USB_CS0) = USB_CS0_CLR_SETUP_END;
  927. ep0status = EP_STATUS_IDLE;
  928. }
  929. if(cs0 & USB_CS0_OUTPKT_RDY) {
  930. if(ep0status == EP_STATUS_IDLE) {
  931. res = ep0_get_setup_pkt();
  932. } else {
  933. res = ep0_get_data_pkt();
  934. }
  935. if(res & USB_READ_NOTIFY) {
  936. notify_ep_process(&usb_endpoints[0], USB_EP_EVENT_NOTIFICATION);
  937. }
  938. if(res & USB_READ_BLOCK) {
  939. return;
  940. }
  941. }
  942. res = ep0_tx();
  943. if(res & USB_WRITE_NOTIFY) {
  944. notify_ep_process(&usb_endpoints[0], USB_EP_EVENT_NOTIFICATION);
  945. }
  946. }
  947. /*---------------------------------------------------------------------------*/
  948. static uint8_t
  949. ep_tx(uint8_t ep_hw)
  950. {
  951. unsigned int len;
  952. uint8_t res = 0;
  953. usb_endpoint_t *ep = EP_STRUCT(ep_hw);
  954. len = ep->xfer_size;
  955. if(ep->halted) {
  956. return 0;
  957. }
  958. if(!ep->buffer || !(ep->buffer->flags & USB_BUFFER_IN)) {
  959. return 0;
  960. }
  961. while(ep->buffer) {
  962. unsigned int copy;
  963. if(ep->buffer->left < len) {
  964. copy = ep->buffer->left;
  965. } else {
  966. copy = len;
  967. }
  968. len -= copy;
  969. ep->buffer->left -= copy;
  970. /*
  971. * Delay somewhat if the previous packet has not yet left the IN FIFO,
  972. * making sure the dog doesn't bark while we're waiting
  973. */
  974. while(REG(USB_CSIL) & USB_CSIL_INPKT_RDY) {
  975. watchdog_periodic();
  976. }
  977. write_hw_buffer(EP_INDEX(ep_hw), ep->buffer->data, copy);
  978. ep->buffer->data += copy;
  979. if(ep->buffer->left == 0) {
  980. if(ep->buffer->flags & USB_BUFFER_SHORT_END) {
  981. if(len == 0) {
  982. /* We keep the buffer in queue so we will send a ZLP next */
  983. break;
  984. } else {
  985. /* Stop looking for more data to send */
  986. len = 0;
  987. }
  988. }
  989. ep->buffer->flags &= ~USB_BUFFER_SUBMITTED;
  990. if(ep->buffer->flags & USB_BUFFER_NOTIFY) {
  991. res |= USB_WRITE_NOTIFY;
  992. }
  993. ep->buffer = ep->buffer->next;
  994. }
  995. if(len == 0) {
  996. /* FIFO full, send */
  997. break;
  998. }
  999. }
  1000. REG(USB_CSIL) |= USB_CSIL_INPKT_RDY;
  1001. return res;
  1002. }
  1003. /*---------------------------------------------------------------------------*/
  1004. static uint8_t
  1005. ep_get_data_pkt(uint8_t ep_hw)
  1006. {
  1007. uint16_t pkt_len;
  1008. uint8_t res;
  1009. uint8_t short_packet = 0;
  1010. usb_endpoint_t *ep = EP_STRUCT(ep_hw);
  1011. if(!ep->buffer) {
  1012. return USB_READ_BLOCK;
  1013. }
  1014. if(ep->buffer->flags & USB_BUFFER_HALT) {
  1015. ep->halted = 1;
  1016. if(!(REG(USB_CSOL) & USB_CSOL_SEND_STALL)) {
  1017. REG(USB_CSOL) |= USB_CSOL_SEND_STALL;
  1018. }
  1019. return 0;
  1020. }
  1021. /* Disambiguate UG CNTL bits */
  1022. pkt_len = REG(USB_CNTL) | (REG(USB_CNTH) << 8);
  1023. if(get_receive_capacity(ep->buffer) < pkt_len) {
  1024. return USB_READ_BLOCK;
  1025. }
  1026. if(pkt_len < ep->xfer_size) {
  1027. short_packet = 1;
  1028. }
  1029. res = fill_buffers(ep->buffer, ep_hw, pkt_len, short_packet);
  1030. REG(USB_CSOL) &= ~USB_CSOL_OUTPKT_RDY;
  1031. return res;
  1032. }
  1033. /*---------------------------------------------------------------------------*/
  1034. static void
  1035. out_ep_interrupt_handler(uint8_t ep_hw)
  1036. {
  1037. uint8_t csl;
  1038. uint8_t res;
  1039. usb_endpoint_t *ep = EP_STRUCT(ep_hw);
  1040. REG(USB_INDEX) = ep_hw;
  1041. csl = REG(USB_CSOL);
  1042. if(csl & USB_CSOL_SENT_STALL) {
  1043. REG(USB_CSOL) &= ~USB_CSOL_SENT_STALL;
  1044. }
  1045. if(csl & USB_CSOL_OVERRUN) {
  1046. /* We lost one isochronous packet */
  1047. REG(USB_CSOL) &= ~USB_CSOL_OVERRUN;
  1048. }
  1049. if(csl & USB_CSOL_OUTPKT_RDY) {
  1050. res = ep_get_data_pkt(ep_hw);
  1051. if(res & USB_READ_NOTIFY) {
  1052. notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
  1053. }
  1054. }
  1055. }
  1056. /*---------------------------------------------------------------------------*/
  1057. static void
  1058. in_ep_interrupt_handler(uint8_t ep_hw)
  1059. {
  1060. uint8_t csl;
  1061. #if USB_ARCH_WRITE_NOTIFY
  1062. uint8_t res;
  1063. usb_endpoint_t *ep = EP_STRUCT(ep_hw);
  1064. #endif
  1065. REG(USB_INDEX) = ep_hw;
  1066. csl = REG(USB_CSIL);
  1067. if(csl & USB_CSIL_SENT_STALL) {
  1068. REG(USB_CSIL) &= ~USB_CSIL_SENT_STALL;
  1069. }
  1070. if(csl & USB_CSIL_UNDERRUN) {
  1071. REG(USB_CSIL) &= ~USB_CSIL_UNDERRUN;
  1072. }
  1073. #if USB_ARCH_WRITE_NOTIFY
  1074. if(!(csl & USB_CSIL_INPKT_RDY)) {
  1075. res = ep_tx(ep_hw);
  1076. if(res & USB_WRITE_NOTIFY) {
  1077. notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
  1078. }
  1079. }
  1080. #endif
  1081. }
  1082. /*---------------------------------------------------------------------------*/
  1083. void
  1084. usb_isr(void)
  1085. {
  1086. uint8_t ep_in_if = REG(USB_IIF) & REG(USB_IIE);
  1087. uint8_t ep_out_if = REG(USB_OIF) & REG(USB_OIE);
  1088. uint8_t common_if = REG(USB_CIF) & REG(USB_CIE);
  1089. uint8_t i;
  1090. ENERGEST_ON(ENERGEST_TYPE_IRQ);
  1091. if(ep_in_if) {
  1092. /* EP0 flag is in the IN Interrupt Flags register */
  1093. if(ep_in_if & USB_IIF_EP0IF) {
  1094. ep0_interrupt_handler();
  1095. }
  1096. for(i = 1; i < 6; i++) {
  1097. if(ep_in_if & EPxIF(i)) {
  1098. in_ep_interrupt_handler(i);
  1099. }
  1100. }
  1101. }
  1102. if(ep_out_if) {
  1103. for(i = 1; i < 6; i++) {
  1104. if(ep_out_if & EPxIF(i)) {
  1105. out_ep_interrupt_handler(i);
  1106. }
  1107. }
  1108. }
  1109. if(common_if & USB_CIF_RSTIF) {
  1110. reset();
  1111. notify_process(USB_EVENT_RESET);
  1112. }
  1113. if(common_if & USB_CIF_RESUMEIF) {
  1114. notify_process(USB_EVENT_RESUME);
  1115. }
  1116. if(common_if & USB_CIF_SUSPENDIF) {
  1117. notify_process(USB_EVENT_SUSPEND);
  1118. }
  1119. ENERGEST_OFF(ENERGEST_TYPE_IRQ);
  1120. }
  1121. /*---------------------------------------------------------------------------*/
  1122. /** @} */