aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2016-05-30 20:06:43 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2016-05-30 20:06:43 +0900
commit1ae3caf7fc8d9d1073684bf2da91b552065a41a7 (patch)
tree36c893427725d31e449b51b3e142edc13774d66e
parenta933eebfd5ee2defdb149a30b31f55010ffefc34 (diff)
USB cleanup
-rw-r--r--ChangeLog8
-rw-r--r--adc.h (renamed from example-fs-bb48/adc.h)0
-rw-r--r--example-cdc/usb_lld.h33
-rw-r--r--example-fs-bb48/usb-cdc.c26
-rw-r--r--mcu/usb-mkl27z.c60
-rw-r--r--mcu/usb-stm32f103.c2
-rw-r--r--usb_lld.h (renamed from example-fs-bb48/usb_lld.h)42
7 files changed, 109 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index 094ae24..8621027 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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