USB cleanup

This commit is contained in:
NIIBE Yutaka
2016-05-30 20:06:43 +09:00
parent a933eebfd5
commit 1ae3caf7fc
7 changed files with 110 additions and 63 deletions

View File

@@ -1,5 +1,13 @@
2016-05-30 NIIBE Yutaka <gniibe@fsij.org> 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/adc-stm32f103.c: New from NeuG.
* mcu/stm32f103.h: New from NeuG. * mcu/stm32f103.h: New from NeuG.

View File

@@ -91,28 +91,29 @@ enum DEVICE_STATE
}; };
void usb_lld_init (uint8_t feature); 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, int usb_lld_reply_request (const void *buf, size_t buflen,
struct req_args *arg); struct req_args *arg);
void usb_lld_rx_enable (int ep_num);
int usb_lld_rx_data_len (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_reset (uint8_t feature);
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);
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, 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_addr, int ep_tx_addr,
int ep_rx_memory_size); int ep_rx_memory_size);
void usb_lld_set_configuration (uint8_t config); void usb_lld_stall_tx (int ep_num);
uint8_t usb_lld_current_configuration (void); void usb_lld_stall_rx (int ep_num);
void usb_lld_set_data_to_recv (void *p, size_t len);
void usb_lld_prepare_shutdown (void); int usb_lld_tx_data_len (int ep_num);
void usb_lld_shutdown (void); 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_interrupt_handler (void); 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);

View File

@@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <chopstx.h> #include <chopstx.h>
#include <string.h> #include <string.h>
#include "board.h"
#include "usb_lld.h" #include "usb_lld.h"
#include "tty.h" #include "tty.h"
@@ -236,7 +237,7 @@ usb_cb_device_reset (void)
usb_lld_reset (VCOM_FEATURE_BUS_POWERED); usb_lld_reset (VCOM_FEATURE_BUS_POWERED);
/* Initialize Endpoint 0 */ /* Initialize Endpoint 0 */
usb_lld_setup_endpoint (ENDP0, 1, 1); usb_lld_setup_endp (ENDP0, 1, 1);
chopstx_mutex_lock (&tty0.mtx); chopstx_mutex_lock (&tty0.mtx);
tty0.inputline_len = 0; tty0.inputline_len = 0;
@@ -364,7 +365,7 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop)
if (interface == 0) if (interface == 0)
{ {
if (!stop) if (!stop)
usb_lld_setup_endpoint (ENDP2, 0, 1); usb_lld_setup_endp (ENDP2, 0, 1);
else else
usb_lld_stall (ENDP2); usb_lld_stall (ENDP2);
} }
@@ -372,8 +373,8 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop)
{ {
if (!stop) if (!stop)
{ {
usb_lld_setup_endpoint (ENDP1, 0, 1); usb_lld_setup_endp (ENDP1, 0, 1);
usb_lld_setup_endpoint (ENDP3, 1, 0); usb_lld_setup_endp (ENDP3, 1, 0);
/* Start with no data receiving (ENDP3 not enabled)*/ /* Start with no data receiving (ENDP3 not enabled)*/
} }
else else
@@ -510,12 +511,14 @@ tty_echo_char (struct tty *t, int c)
put_char_to_ringbuffer (t, c); put_char_to_ringbuffer (t, c);
} }
void 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); struct tty *t = tty_get (-1, ep_num);
(void)len;
(void)success; /* Always, successful. */
if (ep_num == ENDP1) if (ep_num == ENDP1)
{ {
chopstx_mutex_lock (&t->mtx); chopstx_mutex_lock (&t->mtx);
@@ -608,7 +611,7 @@ usb_cb_rx_ready (uint8_t ep_num)
chopstx_mutex_lock (&t->mtx); chopstx_mutex_lock (&t->mtx);
if (t->flag_input_avail == 0) 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); chopstx_mutex_unlock (&t->mtx);
} }
} }
@@ -687,7 +690,7 @@ tty_main (void *arg)
if (len) if (len)
{ {
memcpy (t->send_buf0, line, 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; t->flag_send_ready = 0;
} }
} }
@@ -718,7 +721,8 @@ tty_wait_connection (struct tty *t)
t->flag_input_avail = 0; t->flag_input_avail = 0;
t->send_head = t->send_tail = 0; t->send_head = t->send_tail = 0;
t->inputline_len = 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); 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); chopstx_cond_wait (&t->cnd, &t->mtx);
if (r > 0) if (r > 0)
{ {
usb_lld_tx_enable (ENDP1, p, count); usb_lld_tx_enable_buf (ENDP1, p, count);
t->flag_send_ready = 0; t->flag_send_ready = 0;
} }
chopstx_mutex_unlock (&t->mtx); chopstx_mutex_unlock (&t->mtx);
@@ -827,7 +831,7 @@ tty_recv (struct tty *t, uint8_t *buf, uint32_t *timeout)
r = t->inputline_len; r = t->inputline_len;
memcpy (buf, t->inputline, r); memcpy (buf, t->inputline, r);
t->flag_input_avail = 0; 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; t->inputline_len = 0;
} }
else else

View File

@@ -388,6 +388,11 @@ usb_interrupt_handler (void)
usb_cb_device_reset (); usb_cb_device_reset ();
dev_p->reset++; dev_p->reset++;
} }
else if ((istat_value & USB_IS_TOKDNE))
{
handle_transaction (stat);
dev_p->tkdone++;
}
else if ((istat_value & USB_IS_ERROR)) else if ((istat_value & USB_IS_ERROR))
{ /* Clear Errors. */ { /* Clear Errors. */
USB_CTRL1->ERRSTAT = USB_CTRL1->ERRSTAT; USB_CTRL1->ERRSTAT = USB_CTRL1->ERRSTAT;
@@ -395,14 +400,9 @@ usb_interrupt_handler (void)
/*reset???*/ /*reset???*/
dev_p->error++; dev_p->error++;
} }
else if ((istat_value & USB_IS_TOKDNE))
{
handle_transaction (stat);
dev_p->tkdone++;
}
else if ((istat_value & USB_IS_STALL)) 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)) if (kl27z_ep_is_stall (0))
{ /* It's endpoint 0, recover from erorr. */ { /* It's endpoint 0, recover from erorr. */
@@ -824,6 +824,10 @@ handle_out0 (uint8_t stat)
dev_p->state = STALLED; dev_p->state = STALLED;
} }
#define USB_TOKEN_ACK 0x02
#define USB_TOKEN_IN 0x09
#define USB_TOKEN_SETUP 0x0d
static void static void
handle_transaction (uint8_t stat) handle_transaction (uint8_t stat)
{ {
@@ -835,7 +839,7 @@ handle_transaction (uint8_t stat)
if ((stat & 0x08) == 0) if ((stat & 0x08) == 0)
{ {
ep[0].rx_odd ^= 1; 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 (); handle_setup0 ();
USB_CTRL1->ISTAT = USB_IS_TOKDNE; USB_CTRL1->ISTAT = USB_IS_TOKDNE;
@@ -867,11 +871,36 @@ handle_transaction (uint8_t stat)
} }
else 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++; dev_p->send++;
ep[ep_num].tx_odd ^= 1; 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; USB_CTRL1->ISTAT = USB_IS_TOKDNE;
@@ -905,7 +934,7 @@ usb_lld_reset (uint8_t feature)
} }
void 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) if (n == 0)
{ {
@@ -1002,7 +1031,7 @@ usb_lld_reply_request (const void *buf, size_t buflen, struct req_args *a)
} }
void 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); 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 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); 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].ctrl = (len << 16) | 0x0088 | (data01 << 6);
BD_table[4*n+2+ep[n].tx_odd].buf = (void *)buf; 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 */
}

View File

@@ -972,7 +972,7 @@ void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
if (ep_rx_addr) 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_addr (ep_num, ep_rx_addr);
st103_set_rx_buf_size (ep_num, ep_rx_buf_size); st103_set_rx_buf_size (ep_num, ep_rx_buf_size);
} }

View File

@@ -12,7 +12,7 @@
enum RECIPIENT_TYPE enum RECIPIENT_TYPE
{ {
DEVICE_RECIPIENT, /* Recipient device */ DEVICE_RECIPIENT = 0, /* Recipient device */
INTERFACE_RECIPIENT, /* Recipient interface */ INTERFACE_RECIPIENT, /* Recipient interface */
ENDPOINT_RECIPIENT, /* Recipient endpoint */ ENDPOINT_RECIPIENT, /* Recipient endpoint */
OTHER_RECIPIENT 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); 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, void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
struct req_args *arg); 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); void usb_cb_rx_ready (uint8_t ep_num);
enum { enum {
@@ -85,25 +85,37 @@ enum DEVICE_STATE
}; };
void usb_lld_init (uint8_t feature); void usb_lld_init (uint8_t feature);
int usb_lld_reply_request (const void *buf, size_t buflen, int usb_lld_reply_request (const void *buf, size_t buflen,
struct req_args *arg); 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); 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_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); void usb_lld_set_configuration (uint8_t config);
uint8_t usb_lld_current_configuration (void); uint8_t usb_lld_current_configuration (void);
void usb_lld_prepare_shutdown (void); void usb_lld_prepare_shutdown (void);
void usb_lld_shutdown (void); void usb_lld_shutdown (void);
void usb_interrupt_handler (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