Guest User

Untitled

a guest
Jul 29th, 2019
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 11.63 KB | None | 0 0
  1. diff --git a/soc/app/dcd_tntusb.c b/soc/app/dcd_tntusb.c
  2. index f91174e..5b62d83 100644
  3. --- a/soc/app/dcd_tntusb.c
  4. +++ b/soc/app/dcd_tntusb.c
  5. @@ -11,10 +11,18 @@
  6.  #define USB_CHECK(x) do { if (!(x)) printf("USB: check fail: " #x " (%s:%d)\n", __FILE__, __LINE__); } while (0)
  7.  
  8.  typedef struct {
  9. -   int mem_free_ptr_in;
  10. -   int mem_free_ptr_out;
  11. -   int ep_mps[16];
  12. -   int ep_in_xfer_len[16];
  13. +   uint8_t *buf;
  14. +   uint16_t len;   /* Total transfer length */
  15. +   uint16_t ofs;   /* Offset in the total transfer */
  16. +   uint16_t plen;  /* Length of last queued packet */
  17. +   uint16_t mps;   /* Max Packet Size */
  18. +} g_tntusb_xfer_t;
  19. +
  20. +typedef struct {
  21. +   uint16_t mem_free_ptr_in;
  22. +   uint16_t mem_free_ptr_out;
  23. +   bool ep0_stall;
  24. +   g_tntusb_xfer_t xfer[16][2];
  25.  } g_tntusb_t;
  26.  
  27.  static g_tntusb_t g_usb;
  28. @@ -22,7 +30,7 @@ static g_tntusb_t g_usb;
  29.  static void _usb_data_write(unsigned int dst_ofs, const void *src, int len) {
  30.     /* FIXME unaligned ofs */
  31.     const uint32_t *src_u32 = src;
  32. -   volatile uint32_t *dst_u32 = (volatile uint32_t *)((USB_CORE_OFFSET+USB_TXMEM) + dst_ofs);
  33. +   volatile uint32_t *dst_u32 = (volatile uint32_t *)((USB_DATA_BASE) + dst_ofs);
  34.  
  35.     len = (len + 3) >> 2;
  36.     while (len--)
  37. @@ -31,7 +39,7 @@ static void _usb_data_write(unsigned int dst_ofs, const void *src, int len) {
  38.  
  39.  static void _usb_data_read (void *dst, unsigned int src_ofs, int len) {
  40.     /* FIXME unaligned ofs */
  41. -   volatile uint32_t *src_u32 = (volatile uint32_t *)((USB_CORE_OFFSET+USB_RXMEM) + src_ofs);
  42. +   volatile uint32_t *src_u32 = (volatile uint32_t *)((USB_DATA_BASE) + src_ofs);
  43.     uint32_t *dst_u32 = dst;
  44.  
  45.     int i = len >> 2;
  46. @@ -125,11 +133,137 @@ void dcd_remote_wakeup(uint8_t rhport)
  47.  /* DCD Endpoint port
  48.   *------------------------------------------------------------------*/
  49.  
  50. +static bool
  51. +_ep_advance_xfer_in(const uint8_t epnum)
  52. +{
  53. +   g_tntusb_xfer_t *xf = &g_usb.xfer[epnum][TUSB_DIR_IN];
  54. +   uint32_t bds = tntusb_ep_regs[epnum].in.bd[0].csr;
  55. +   bool pkt_done = false;
  56. +   int len;
  57. +
  58. +   /* Handle EP0 stalls */
  59. +   if ((epnum == 0) && g_usb.ep0_stall) {
  60. +       if ((bds & TNTUSB_BD_STATE_MSK) != TNTUSB_BD_STATE_RDY_STALL)
  61. +           tntusb_ep_regs[epnum].in.bd[0].csr = TNTUSB_BD_STATE_RDY_STALL;
  62. +       return false;
  63. +   }
  64. +
  65. +   /* Just retry on errors */
  66. +   if ((bds & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_ERR) {
  67. +       tntusb_ep_regs[epnum].in.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(xf->plen);
  68. +       return true;
  69. +   }
  70. +
  71. +   /* Packet done ? */
  72. +   if ((bds & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_OK)
  73. +   {
  74. +       tntusb_ep_regs[epnum].in.bd[0].csr = 0;
  75. +       xf->ofs += xf->plen;
  76. +
  77. +       if ((xf->ofs == xf->len) && (((xf->len % xf->mps) != 0) || ~xf->plen))
  78. +       {
  79. +           len = xf->len;
  80. +
  81. +           xf->buf  = NULL;
  82. +           xf->len  = 0;
  83. +           xf->ofs  = 0;
  84. +           xf->plen = 0;
  85. +
  86. +           dcd_event_xfer_complete(0, epnum | 0x80, len, XFER_RESULT_SUCCESS, true);
  87. +       }
  88. +       pkt_done = true;
  89. +   }
  90. +
  91. +   /* Need to submit another one */
  92. +   if (pkt_done || ((bds & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_NONE))
  93. +   {
  94. +       if (xf->buf) {
  95. +           /* Select packet size */
  96. +           xf->plen = xf->len - xf->ofs;
  97. +           if (xf->plen > xf->mps)
  98. +               xf->plen = xf->mps;
  99. +
  100. +           /* Fill data buffer */
  101. +           _usb_data_write(tntusb_ep_regs[epnum].in.bd[0].ptr, &xf->buf[xf->ofs], xf->plen);
  102. +
  103. +           /* Submit packet */
  104. +           tntusb_ep_regs[epnum].in.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(xf->plen);
  105. +       }
  106. +
  107. +       return true;
  108. +   }
  109. +
  110. +   return pkt_done;
  111. +}
  112. +
  113. +static bool
  114. +_ep_advance_xfer_out(const uint8_t epnum)
  115. +{
  116. +   g_tntusb_xfer_t *xf = &g_usb.xfer[epnum][TUSB_DIR_OUT];
  117. +   uint32_t bds = tntusb_ep_regs[epnum].out.bd[0].csr;
  118. +   bool pkt_done = false;
  119. +   int len;
  120. +
  121. +   /* Handle EP0 stalls */
  122. +   if ((epnum == 0) && g_usb.ep0_stall) {
  123. +       if ((bds & TNTUSB_BD_STATE_MSK) != TNTUSB_BD_STATE_RDY_STALL)
  124. +           tntusb_ep_regs[epnum].out.bd[0].csr = TNTUSB_BD_STATE_RDY_STALL;
  125. +       return false;
  126. +   }
  127. +
  128. +   /* Just retry on errors */
  129. +   if ((bds & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_ERR) {
  130. +       tntusb_ep_regs[epnum].out.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(xf->mps);
  131. +       return true;
  132. +   }
  133. +
  134. +   /* Packet done */
  135. +   if ((bds & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_OK)
  136. +   {
  137. +       xf->plen = (bds & TNTUSB_BD_LEN_MSK) - 2;
  138. +       if (xf->plen > (xf->len - xf->ofs))
  139. +           xf->plen = xf->len - xf->ofs;
  140. +
  141. +       tntusb_ep_regs[epnum].out.bd[0].csr = 0;
  142. +
  143. +       if (xf->plen) {
  144. +           _usb_data_read(&xf->buf[xf->ofs], tntusb_ep_regs[epnum].out.bd[0].ptr, xf->plen);
  145. +           xf->ofs += xf->plen;
  146. +       }
  147. +
  148. +       /* end of transfer when requested length is reached, or a short transfer from host */
  149. +       if ((xf->plen < xf->mps) || (xf->len == xf->ofs))
  150. +       {
  151. +           len = xf->ofs;
  152. +
  153. +           xf->buf  = NULL;
  154. +           xf->len  = 0;
  155. +           xf->ofs  = 0;
  156. +           xf->plen = 0;
  157. +
  158. +           dcd_event_xfer_complete(0, epnum, len, XFER_RESULT_SUCCESS, true);
  159. +       }
  160. +
  161. +       pkt_done = true;
  162. +   }
  163. +
  164. +   /* Need to submit another one */
  165. +   if (pkt_done || ((bds & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_NONE))
  166. +   {
  167. +       if (xf->buf)
  168. +           tntusb_ep_regs[epnum].out.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(xf->mps);
  169. +       return true;
  170. +   }
  171. +
  172. +   return pkt_done;
  173. +}
  174. +
  175.  bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) {
  176.     (void) rhport;
  177.     uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
  178.     uint8_t const dir   = tu_edpt_dir(desc_edpt->bEndpointAddress);
  179. -   g_usb.ep_mps[epnum]=desc_edpt->wMaxPacketSize.size;
  180. +
  181. +   g_usb.xfer[epnum][dir].mps = desc_edpt->wMaxPacketSize.size;
  182.  
  183.     int type=0;
  184.     if (desc_edpt->bmAttributes.xfer==TUSB_XFER_CONTROL) type=TNTUSB_EP_TYPE_CTRL;
  185. @@ -154,12 +288,16 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) {
  186.  
  187.         g_usb.mem_free_ptr_out+=desc_edpt->wMaxPacketSize.size+8; //add setup packet
  188.         g_usb.mem_free_ptr_in+=desc_edpt->wMaxPacketSize.size;
  189. +
  190. +       g_usb.xfer[0][TUSB_DIR_IN].mps  = desc_edpt->wMaxPacketSize.size;
  191. +       g_usb.xfer[0][TUSB_DIR_OUT].mps = desc_edpt->wMaxPacketSize.size;
  192. +
  193.     } else if (dir == TUSB_DIR_OUT) {
  194.         printf("Setting up out endpoint %d\n", epnum);
  195.         USB_CHECK(epnum!=0);
  196.         tntusb_ep_regs[epnum].out.status = type;
  197.         tntusb_ep_regs[epnum].out.bd[0].ptr = g_usb.mem_free_ptr_out;
  198. -       tntusb_ep_regs[epnum].out.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(desc_edpt->wMaxPacketSize.size);
  199. +       tntusb_ep_regs[epnum].out.bd[0].csr = 0;
  200.         g_usb.mem_free_ptr_out+=desc_edpt->wMaxPacketSize.size;
  201.     } else {
  202.         printf("Setting up in endpoint %d\n", epnum);
  203. @@ -177,31 +315,73 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
  204.  
  205.     uint8_t const epnum = tu_edpt_number(ep_addr);
  206.     uint8_t const dir   = tu_edpt_dir(ep_addr);
  207. -   printf ("dcd_edpt_xfer: ep %d dir %s, len %d\n", epnum, (dir==TUSB_DIR_OUT)?"out":"in", total_bytes);
  208. -
  209. -   if (dir==TUSB_DIR_OUT) {
  210. -       if (buffer) _usb_data_read(buffer, tntusb_ep_regs[epnum].out.bd[0].ptr, total_bytes);
  211. -       tntusb_ep_regs[epnum].out.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(g_usb.ep_mps[epnum]);
  212. -   } else {
  213. -       if (buffer) _usb_data_write(tntusb_ep_regs[epnum].in.bd[0].ptr, buffer, total_bytes);
  214. -       tntusb_ep_regs[epnum].in.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(total_bytes);
  215. -       g_usb.ep_in_xfer_len[epnum]=total_bytes;
  216. +   printf ("dcd_edpt_xfer: ep %d dir %s, len %d, buf %08x\n", epnum, (dir==TUSB_DIR_OUT)?"out":"in", total_bytes, buffer);
  217. +
  218. +   g_usb.xfer[epnum][dir].buf = buffer;
  219. +   g_usb.xfer[epnum][dir].len = total_bytes;
  220. +   g_usb.xfer[epnum][dir].ofs = 0;
  221. +
  222. +   if (!buffer) {
  223. +       /* ZLP */
  224. +       if (dir == TUSB_DIR_IN) {
  225. +           tntusb_ep_regs[epnum].in.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(0);
  226. +       } else {
  227. +           tntusb_ep_regs[epnum].out.bd[0].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(0);
  228. +       }
  229.     }
  230. +
  231. +   if (dir == TUSB_DIR_OUT)
  232. +       _ep_advance_xfer_out(epnum);
  233. +   else
  234. +       _ep_advance_xfer_in(epnum);
  235. +
  236.     return true;
  237.  }
  238.  
  239.  void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) {
  240.     (void) rhport;
  241.     printf("STALL ep %d\n", ep_addr);
  242. +
  243.     uint8_t const epnum = tu_edpt_number(ep_addr);
  244. -   tntusb_ep_regs[epnum].out.bd[0].csr |= TNTUSB_BD_STATE_RDY_STALL;
  245. +   uint8_t const dir   = tu_edpt_dir(ep_addr);
  246. +
  247. +   if (epnum == 0) {
  248. +       /* For EP0 we can't halt it since we still need to receive SETUP */
  249. +       /* So we need to manually queue STALL */
  250. +       if (dir == TUSB_DIR_OUT) {
  251. +           g_usb.ep0_stall = true;
  252. +           tntusb_ep_regs[epnum].out.bd[0].csr = TNTUSB_BD_STATE_RDY_STALL;
  253. +       } else {
  254. +           g_usb.ep0_stall = true;
  255. +           tntusb_ep_regs[epnum].in.bd[0].csr = TNTUSB_BD_STATE_RDY_STALL;
  256. +       }
  257. +   } else {
  258. +       /* Simply halt the end point */
  259. +       if (dir == TUSB_DIR_OUT) {
  260. +           tntusb_ep_regs[epnum].out.status |= TNTUSB_EP_TYPE_HALTED;
  261. +       } else {
  262. +           tntusb_ep_regs[epnum].in.status  |= TNTUSB_EP_TYPE_HALTED;
  263. +       }
  264. +   }
  265.  }
  266.  
  267.  void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) {
  268.     (void) rhport;
  269.     printf("UNSTALL ep %d\n", ep_addr);
  270. +
  271.     uint8_t const epnum = tu_edpt_number(ep_addr);
  272. -   tntusb_ep_regs[epnum].out.bd[0].csr &= ~TNTUSB_BD_STATE_RDY_STALL;
  273. +   uint8_t const dir   = tu_edpt_dir(ep_addr);
  274. +
  275. +   if (epnum == 0) {
  276. +       /* This is handled when we get a SETUP packet */
  277. +   } else {
  278. +       /* Resume the end point */
  279. +       if (dir == TUSB_DIR_OUT) {
  280. +           tntusb_ep_regs[epnum].out.status &= ~TNTUSB_EP_TYPE_HALTED;
  281. +       } else {
  282. +           tntusb_ep_regs[epnum].in.status  &= ~TNTUSB_EP_TYPE_HALTED;
  283. +       }
  284. +   }
  285.  }
  286.  
  287.  /*------------------------------------------------------------------*/
  288. @@ -216,6 +396,7 @@ void usb_poll(void) {
  289.         }
  290.         printf("Reset pending: doing that\n");
  291.         _usb_hw_reset(true);
  292. +       memset(&g_usb.xfer, 0x00, sizeof(g_usb.xfer));
  293.         dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true);
  294.         g_usb.mem_free_ptr_out=0;
  295.         g_usb.mem_free_ptr_in=0;
  296. @@ -232,37 +413,41 @@ void usb_poll(void) {
  297.         dcd_event_bus_signal(0, DCD_EVENT_SOF, true);
  298.     }
  299.  
  300. -   //setup handling
  301. -   uint32_t bds_setup=tntusb_ep_regs[0].out.bd[1].csr;
  302. -   if ((tntusb_ep_regs[0].out.bd[1].csr & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_OK) {
  303. -       //Setup packet received. Read and ack manually.
  304. +   // Handle endpoints
  305. +   for (int ep=0; ep<16; ep++) {
  306. +       _ep_advance_xfer_in(ep);
  307. +       _ep_advance_xfer_out(ep);
  308. +   }
  309. +
  310. +   // Setup handling
  311. +   uint32_t bds_setup = tntusb_ep_regs[0].out.bd[1].csr;
  312. +
  313. +   if ((bds_setup & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_OK) {
  314. +       // Setup packet received. Read and ack manually.
  315.         _usb_data_read(tmpbuf, tntusb_ep_regs[0].out.bd[1].ptr, 8);
  316.         printf("Setup packet rcvd:");
  317.         for (int i=0; i<8; i++) printf("%02X ", tmpbuf[i]);
  318.         printf("\n");
  319.         tntusb_ep_regs[0].out.bd[1].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(8);
  320. -       //clear in/out
  321. +
  322. +       // Clear in/out/stall
  323.         tntusb_ep_regs[0].in.bd[0].csr = 0;
  324.         tntusb_ep_regs[0].out.bd[0].csr = 0;
  325. -       //Make sure DT=1 for IN endpoint after a SETUP
  326. +       g_usb.ep0_stall = false;
  327. +
  328. +       // Release lockout
  329. +       tntusb_regs->ar = TNTUSB_AR_CEL_RELEASE;
  330. +
  331. +       // Make sure DT=1 for IN endpoint after a SETUP
  332.         tntusb_ep_regs[0].in.status = TNTUSB_EP_TYPE_CTRL | TNTUSB_EP_DT_BIT;
  333. +
  334. +       // Notify tinyusb stack
  335.         dcd_event_setup_received(0, tmpbuf, true);
  336. -       tntusb_regs->ar = TNTUSB_AR_CEL_RELEASE;
  337. -   }
  338. +   } else if ((bds_setup & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_ERR) {
  339. +       /* Just setup a new one ... */
  340. +       tntusb_ep_regs[0].out.bd[1].csr = TNTUSB_BD_STATE_RDY_DATA | TNTUSB_BD_LEN(8);
  341.  
  342. -   //handle endpoints
  343. -   for (int ep=0; ep<16; ep++) {
  344. -       uint32_t in_csr=tntusb_ep_regs[ep].in.bd[0].csr;
  345. -       if ((in_csr & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_OK) {
  346. -           printf("IN xfer done on ep %d: %d bytes\n", ep, g_usb.ep_in_xfer_len[ep]);
  347. -           tntusb_ep_regs[ep].in.bd[0].csr=0;
  348. -           dcd_event_xfer_complete(0, ep, g_usb.ep_in_xfer_len[ep], XFER_RESULT_SUCCESS, true);
  349. -       }
  350. -       uint32_t out_csr=tntusb_ep_regs[ep].out.bd[0].csr;
  351. -       if ((out_csr & TNTUSB_BD_STATE_MSK) == TNTUSB_BD_STATE_DONE_OK) {
  352. -           printf("OUT xfer done on ep %d: %d bytes\n", ep, out_csr & TNTUSB_BD_LEN_MSK);
  353. -           dcd_event_xfer_complete(0, ep, out_csr & TNTUSB_BD_LEN_MSK, XFER_RESULT_SUCCESS, true);
  354. -       }
  355. +       /* FIXME: can't check of the lockout is triggered if an error happens ... */
  356.     }
  357.  }
Advertisement
Add Comment
Please, Sign In to add comment