diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2016-05-30 20:06:43 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2016-05-30 20:06:43 +0900 |
commit | 1ae3caf7fc8d9d1073684bf2da91b552065a41a7 (patch) | |
tree | 36c893427725d31e449b51b3e142edc13774d66e /mcu | |
parent | a933eebfd5ee2defdb149a30b31f55010ffefc34 (diff) |
USB cleanup
Diffstat (limited to 'mcu')
-rw-r--r-- | mcu/usb-mkl27z.c | 60 | ||||
-rw-r--r-- | mcu/usb-stm32f103.c | 2 |
2 files changed, 42 insertions, 20 deletions
diff --git a/mcu/usb-mkl27z.c b/mcu/usb-mkl27z.c index 385e5a8..5a21dd8 100644 --- a/mcu/usb-mkl27z.c +++ b/mcu/usb-mkl27z.c @@ -388,6 +388,11 @@ usb_interrupt_handler (void) usb_cb_device_reset (); dev_p->reset++; } + else if ((istat_value & USB_IS_TOKDNE)) + { + handle_transaction (stat); + dev_p->tkdone++; + } else if ((istat_value & USB_IS_ERROR)) { /* Clear Errors. */ USB_CTRL1->ERRSTAT = USB_CTRL1->ERRSTAT; @@ -395,14 +400,9 @@ usb_interrupt_handler (void) /*reset???*/ dev_p->error++; } - else if ((istat_value & USB_IS_TOKDNE)) - { - handle_transaction (stat); - dev_p->tkdone++; - } else if ((istat_value & USB_IS_STALL)) { - /* ??? stat includes ep_num in this case ???: No, it doesn't */ + /* Does STAT have ENDPOINT info in this case?: No, it doesn't. */ if (kl27z_ep_is_stall (0)) { /* It's endpoint 0, recover from erorr. */ @@ -824,6 +824,10 @@ handle_out0 (uint8_t stat) dev_p->state = STALLED; } +#define USB_TOKEN_ACK 0x02 +#define USB_TOKEN_IN 0x09 +#define USB_TOKEN_SETUP 0x0d + static void handle_transaction (uint8_t stat) { @@ -835,7 +839,7 @@ handle_transaction (uint8_t stat) if ((stat & 0x08) == 0) { ep[0].rx_odd ^= 1; - if (TOK_PID (BD_table[odd].ctrl) == 0x0d) + if (TOK_PID (BD_table[odd].ctrl) == USB_TOKEN_SETUP) { handle_setup0 (); USB_CTRL1->ISTAT = USB_IS_TOKDNE; @@ -867,11 +871,36 @@ handle_transaction (uint8_t stat) } else { - /* XXX: Can be NAK. Check BDT if it's NAK or not. */ + /* + * IN transaction is usually in a sequence like: + * + * -----time------> + * host: IN ACK + * device: DATA0/1 + * + * It is not described in the specification (it's + * ambiguous), but it is actually possible for some host + * implementation to send back a NAK on erroneous case like + * a device sent oversized data. + * + * -----time------> + * host: IN NAK + * device: DATA0/1 + * + * We do our best to distinguish successful tx and tx with + * failure. + * + */ + uint32_t dmaerr = (USB_CTRL1->ERRSTAT & (1 << 5)); + int success = (dmaerr == 0); + uint32_t len = (BD_table[4*ep_num+2+odd].ctrl >> 16)&0x3ff; + + if (!success) + USB_CTRL1->ERRSTAT = dmaerr; /* Clear error. */ dev_p->send++; ep[ep_num].tx_odd ^= 1; - usb_cb_tx_done (ep_num); + usb_cb_tx_done (ep_num, len, success); } USB_CTRL1->ISTAT = USB_IS_TOKDNE; @@ -905,7 +934,7 @@ usb_lld_reset (uint8_t feature) } void -usb_lld_setup_endpoint (int n, int rx_en, int tx_en) +usb_lld_setup_endp (int n, int rx_en, int tx_en) { if (n == 0) { @@ -1002,7 +1031,7 @@ usb_lld_reply_request (const void *buf, size_t buflen, struct req_args *a) } void -usb_lld_rx_enable (int n, void *buf, size_t len) +usb_lld_rx_enable_buf (int n, void *buf, size_t len) { int data01 = !((BD_table[4*n+!ep[n].rx_odd].ctrl >> 6)&1); @@ -1018,17 +1047,10 @@ usb_lld_rx_data_len (int n) void -usb_lld_tx_enable (uint8_t n, const void *buf, size_t len) +usb_lld_tx_enable_buf (int n, const void *buf, size_t len) { int data01 = !((BD_table[4*n+2+!ep[n].tx_odd].ctrl >> 6)&1); BD_table[4*n+2+ep[n].tx_odd].ctrl = (len << 16) | 0x0088 | (data01 << 6); BD_table[4*n+2+ep[n].tx_odd].buf = (void *)buf; } - -int -usb_lld_tx_result (int ep_num) -{ - (void)ep_num; - return 0; /* XXX: return -1 when NAK */ -} diff --git a/mcu/usb-stm32f103.c b/mcu/usb-stm32f103.c index a709fb6..73c32c3 100644 --- a/mcu/usb-stm32f103.c +++ b/mcu/usb-stm32f103.c @@ -972,7 +972,7 @@ void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind, if (ep_rx_addr) { - ep_rxtx_status |= EP_RX_VALID; + ep_rxtx_status |= EP_RX_NAK; st103_set_rx_addr (ep_num, ep_rx_addr); st103_set_rx_buf_size (ep_num, ep_rx_buf_size); } |