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 | |
parent | a933eebfd5ee2defdb149a30b31f55010ffefc34 (diff) |
USB cleanup
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | adc.h (renamed from example-fs-bb48/adc.h) | 0 | ||||
-rw-r--r-- | example-cdc/usb_lld.h | 33 | ||||
-rw-r--r-- | example-fs-bb48/usb-cdc.c | 26 | ||||
-rw-r--r-- | mcu/usb-mkl27z.c | 60 | ||||
-rw-r--r-- | mcu/usb-stm32f103.c | 2 | ||||
-rw-r--r-- | usb_lld.h (renamed from example-fs-bb48/usb_lld.h) | 42 |
7 files changed, 109 insertions, 62 deletions
@@ -1,5 +1,13 @@ 2016-05-30 NIIBE Yutaka <gniibe@fsij.org> + * mcu/usb-stm32f103.c (usb_lld_setup_endpoint): Start with + EP_RX_NAK. + + * mcu/usb-mkl27z.c (handle_transaction): Handle NAK case. + (usb_lld_setup_endp): Rename from usb_lld_setup_endpoint. + (usb_lld_rx_enable_buf): Rename from usb_lld_rx_enable. + (usb_lld_tx_enable_buf): Rename from usb_lld_tx_enable. + * mcu/adc-stm32f103.c: New from NeuG. * mcu/stm32f103.h: New from NeuG. diff --git a/example-fs-bb48/adc.h b/adc.h index 1a009f7..1a009f7 100644 --- a/example-fs-bb48/adc.h +++ b/adc.h diff --git a/example-cdc/usb_lld.h b/example-cdc/usb_lld.h index 3710f20..da9396d 100644 --- a/example-cdc/usb_lld.h +++ b/example-cdc/usb_lld.h @@ -91,28 +91,29 @@ enum DEVICE_STATE }; void usb_lld_init (uint8_t feature); -void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n); -void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n); -void usb_lld_stall_tx (int ep_num); -void usb_lld_stall_rx (int ep_num); -int usb_lld_tx_data_len (int ep_num); -void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len); -void usb_lld_tx_enable (int ep_num, size_t len); -void usb_lld_write (uint8_t ep_num, const void *buf, size_t len); int usb_lld_reply_request (const void *buf, size_t buflen, struct req_args *arg); -void usb_lld_rx_enable (int ep_num); int usb_lld_rx_data_len (int ep_num); -void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len); void usb_lld_reset (uint8_t feature); -void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind, - int ep_rx_addr, int ep_tx_addr, - int ep_rx_memory_size); void usb_lld_set_configuration (uint8_t config); uint8_t usb_lld_current_configuration (void); -void usb_lld_set_data_to_recv (void *p, size_t len); - void usb_lld_prepare_shutdown (void); void usb_lld_shutdown (void); - void usb_interrupt_handler (void); +void usb_lld_set_data_to_recv (void *p, size_t len); + +void usb_lld_tx_enable (int ep_num, size_t len); +void usb_lld_rx_enable (int ep_num); + +void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind, + int ep_rx_addr, int ep_tx_addr, + int ep_rx_memory_size); +void usb_lld_stall_tx (int ep_num); +void usb_lld_stall_rx (int ep_num); + +int usb_lld_tx_data_len (int ep_num); +void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len); +void usb_lld_write (uint8_t ep_num, const void *buf, size_t len); +void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n); +void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n); +void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len); diff --git a/example-fs-bb48/usb-cdc.c b/example-fs-bb48/usb-cdc.c index c950362..67a6e0e 100644 --- a/example-fs-bb48/usb-cdc.c +++ b/example-fs-bb48/usb-cdc.c @@ -2,6 +2,7 @@ #include <stdlib.h> #include <chopstx.h> #include <string.h> +#include "board.h" #include "usb_lld.h" #include "tty.h" @@ -236,7 +237,7 @@ usb_cb_device_reset (void) usb_lld_reset (VCOM_FEATURE_BUS_POWERED); /* Initialize Endpoint 0 */ - usb_lld_setup_endpoint (ENDP0, 1, 1); + usb_lld_setup_endp (ENDP0, 1, 1); chopstx_mutex_lock (&tty0.mtx); tty0.inputline_len = 0; @@ -364,7 +365,7 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop) if (interface == 0) { if (!stop) - usb_lld_setup_endpoint (ENDP2, 0, 1); + usb_lld_setup_endp (ENDP2, 0, 1); else usb_lld_stall (ENDP2); } @@ -372,8 +373,8 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop) { if (!stop) { - usb_lld_setup_endpoint (ENDP1, 0, 1); - usb_lld_setup_endpoint (ENDP3, 1, 0); + usb_lld_setup_endp (ENDP1, 0, 1); + usb_lld_setup_endp (ENDP3, 1, 0); /* Start with no data receiving (ENDP3 not enabled)*/ } else @@ -510,12 +511,14 @@ tty_echo_char (struct tty *t, int c) put_char_to_ringbuffer (t, c); } - void -usb_cb_tx_done (uint8_t ep_num) +usb_cb_tx_done (uint8_t ep_num, uint32_t len, int success) { struct tty *t = tty_get (-1, ep_num); + (void)len; + (void)success; /* Always, successful. */ + if (ep_num == ENDP1) { chopstx_mutex_lock (&t->mtx); @@ -608,7 +611,7 @@ usb_cb_rx_ready (uint8_t ep_num) chopstx_mutex_lock (&t->mtx); if (t->flag_input_avail == 0) - usb_lld_rx_enable (ENDP3, t->recv_buf0, 64); + usb_lld_rx_enable_buf (ENDP3, t->recv_buf0, 64); chopstx_mutex_unlock (&t->mtx); } } @@ -687,7 +690,7 @@ tty_main (void *arg) if (len) { memcpy (t->send_buf0, line, len); - usb_lld_tx_enable (ENDP1, t->send_buf0, len); + usb_lld_tx_enable_buf (ENDP1, t->send_buf0, len); t->flag_send_ready = 0; } } @@ -718,7 +721,8 @@ tty_wait_connection (struct tty *t) t->flag_input_avail = 0; t->send_head = t->send_tail = 0; t->inputline_len = 0; - usb_lld_rx_enable (ENDP3, t->recv_buf0, 64); /* Accept input for line */ + /* Accept input for line */ + usb_lld_rx_enable_buf (ENDP3, t->recv_buf0, 64); chopstx_mutex_unlock (&t->mtx); } @@ -751,7 +755,7 @@ tty_send (struct tty *t, const uint8_t *buf, int len) chopstx_cond_wait (&t->cnd, &t->mtx); if (r > 0) { - usb_lld_tx_enable (ENDP1, p, count); + usb_lld_tx_enable_buf (ENDP1, p, count); t->flag_send_ready = 0; } chopstx_mutex_unlock (&t->mtx); @@ -827,7 +831,7 @@ tty_recv (struct tty *t, uint8_t *buf, uint32_t *timeout) r = t->inputline_len; memcpy (buf, t->inputline, r); t->flag_input_avail = 0; - usb_lld_rx_enable (ENDP3, t->recv_buf0, 64); + usb_lld_rx_enable_buf (ENDP3, t->recv_buf0, 64); t->inputline_len = 0; } else 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); } diff --git a/example-fs-bb48/usb_lld.h b/usb_lld.h index b2ce4fb..1b4eb4b 100644 --- a/example-fs-bb48/usb_lld.h +++ b/usb_lld.h @@ -12,7 +12,7 @@ enum RECIPIENT_TYPE { - DEVICE_RECIPIENT, /* Recipient device */ + DEVICE_RECIPIENT = 0, /* Recipient device */ INTERFACE_RECIPIENT, /* Recipient interface */ ENDPOINT_RECIPIENT, /* Recipient endpoint */ OTHER_RECIPIENT @@ -57,7 +57,7 @@ int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, int usb_cb_handle_event (uint8_t event_type, uint16_t value); void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg); -void usb_cb_tx_done (uint8_t ep_num); +void usb_cb_tx_done (uint8_t ep_num, uint32_t len, int success); void usb_cb_rx_ready (uint8_t ep_num); enum { @@ -85,25 +85,37 @@ enum DEVICE_STATE }; void usb_lld_init (uint8_t feature); - int usb_lld_reply_request (const void *buf, size_t buflen, struct req_args *arg); -void usb_lld_set_data_to_recv (void *p, size_t len); - -void usb_lld_tx_enable (uint8_t ep_num, const void *buf, size_t len); -int usb_lld_tx_result (int ep_num); - -void usb_lld_rx_enable (int ep_num, void *buf, size_t len); int usb_lld_rx_data_len (int ep_num); - -void usb_lld_stall (int ep_num); - void usb_lld_reset (uint8_t feature); -void usb_lld_setup_endpoint (int n, int rx_en, int tx_en); void usb_lld_set_configuration (uint8_t config); uint8_t usb_lld_current_configuration (void); - void usb_lld_prepare_shutdown (void); void usb_lld_shutdown (void); - void usb_interrupt_handler (void); +void usb_lld_set_data_to_recv (void *p, size_t len); + +#ifdef MCU_KINETIS_L +void usb_lld_tx_enable_buf (int ep_num, const void *buf, size_t len); +void usb_lld_rx_enable_buf (int ep_num, void *buf, size_t len); + +void usb_lld_setup_endp (int ep_num, int rx_en, int tx_en); +void usb_lld_stall (int ep_num); +#else +void usb_lld_tx_enable (int ep_num, size_t len); +void usb_lld_rx_enable (int ep_num); + +void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind, + int ep_rx_addr, int ep_tx_addr, + int ep_rx_memory_size); +void usb_lld_stall_tx (int ep_num); +void usb_lld_stall_rx (int ep_num); + +int usb_lld_tx_data_len (int ep_num); +void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len); +void usb_lld_write (uint8_t ep_num, const void *buf, size_t len); +void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n); +void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n); +void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len); +#endif |