diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2016-04-18 17:23:10 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2016-04-18 17:23:10 +0900 |
commit | 0bbb43dd3a943285ffb5462db468f7af29c4bbfb (patch) | |
tree | 322f6b9a472dc2f1446ac882943c12b072ac0d77 /example-fs-bb48 | |
parent | 82749ab97af6ec1de605f0638d44999c3b50eadf (diff) |
Fix USB driver and example
Diffstat (limited to 'example-fs-bb48')
-rw-r--r-- | example-fs-bb48/sample.c | 11 | ||||
-rw-r--r-- | example-fs-bb48/stream.h | 4 | ||||
-rw-r--r-- | example-fs-bb48/usb-cdc.c | 128 | ||||
-rw-r--r-- | example-fs-bb48/usb_kl27z.c | 2 |
4 files changed, 132 insertions, 13 deletions
diff --git a/example-fs-bb48/sample.c b/example-fs-bb48/sample.c index 92ecc9b..aa69144 100644 --- a/example-fs-bb48/sample.c +++ b/example-fs-bb48/sample.c @@ -199,7 +199,7 @@ main (int argc, const char *argv[]) /* Send ZLP at the beginning. */ stream_send (st, s, 0); - memcpy (s, "xx: Hello, World with Chopstx!\r\n\000", 32); + memcpy (s, "xx: Hello, World with Chopstx!\r\n", 32); s[0] = hexchar (count >> 4); s[1] = hexchar (count & 0x0f); count++; @@ -209,14 +209,19 @@ main (int argc, const char *argv[]) while (1) { - int size = stream_recv (st, s); + int size = stream_recv (st, s + 4); if (size < 0) break; if (size >= 0) { - if (stream_send (st, s, size) < 0) + s[0] = hexchar (size >> 4); + s[1] = hexchar (size & 0x0f); + + s[size + 4] = '\r'; + s[size + 5] = '\n'; + if (stream_send (st, s, size + 6) < 0) break; } diff --git a/example-fs-bb48/stream.h b/example-fs-bb48/stream.h index 15cbe63..77b7014 100644 --- a/example-fs-bb48/stream.h +++ b/example-fs-bb48/stream.h @@ -9,8 +9,10 @@ struct stream { chopstx_mutex_t mtx; chopstx_cond_t cnd; + int sending; + unsigned int recv_len; + uint8_t recv_buf[BUFSIZE]; uint8_t buf_send[BUFSIZE]; /* Not yet used. */ - uint8_t buf_recv[BUFSIZE]; /* Not yet used. */ uint8_t cnt_send_head; /* Not yet used. */ uint8_t cnt_send_tail; /* Not yet used. */ uint8_t cnt_recv_head; /* Not yet used. */ diff --git a/example-fs-bb48/usb-cdc.c b/example-fs-bb48/usb-cdc.c index 290a4fd..30d4ccd 100644 --- a/example-fs-bb48/usb-cdc.c +++ b/example-fs-bb48/usb-cdc.c @@ -1,9 +1,20 @@ #include <stdint.h> #include <stdlib.h> #include <chopstx.h> +#include <string.h> #include "usb_lld.h" #include "stream.h" +static uint8_t send_buf[64]; +static unsigned int send_len; +static uint8_t send_buf1[64]; + +static uint8_t recv_buf[64]; +static unsigned int recv_len; + +static uint8_t inputline[64]; +static unsigned int inputline_len; + static struct stream stream; #define USB_CDC_REQ_SET_LINE_CODING 0x20 @@ -184,6 +195,8 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg) stream.flags &= ~FLAG_CONNECTED; stream.flags |= ((arg->value & CDC_CTRL_DTR) != 0)? FLAG_CONNECTED : 0; chopstx_cond_signal (&stream.cnd); + recv_len = 0; + usb_lld_rx_enable (ENDP3, recv_buf, 64); chopstx_mutex_unlock (&stream.mtx); } } @@ -389,36 +402,133 @@ usb_cb_interface (uint8_t cmd, struct req_args *arg) } +static void +stream_echo_char (int c) +{ + chopstx_mutex_lock (&stream.mtx); + if (send_len < sizeof (send_buf)) + send_buf[send_len++] = c; + else + { + /* All that we can is ignoring the output. */ + ; + } + + if (stream.sending == 0) + { + memcpy (send_buf1, send_buf, send_len); + usb_lld_tx_enable (ENDP1, send_buf1, send_len); + send_len = 0; + stream.sending = 1; + } + chopstx_mutex_unlock (&stream.mtx); +} + + void usb_cb_tx_done (uint8_t ep_num) { if (ep_num == ENDP1) { chopstx_mutex_lock (&stream.mtx); - if ((stream.flags & FLAG_SEND_AVAIL)) + stream.sending = 0; + if (send_len) { - stream.flags &= ~FLAG_SEND_AVAIL; - chopstx_cond_signal (&stream.cnd); + stream.sending = 1; + memcpy (send_buf1, send_buf, send_len); + usb_lld_tx_enable (ENDP1, send_buf1, send_len); + send_len = 0; + } + else + { + if ((stream.flags & FLAG_SEND_AVAIL)) + { + stream.flags &= ~FLAG_SEND_AVAIL; + chopstx_cond_signal (&stream.cnd); + } } chopstx_mutex_unlock (&stream.mtx); } else if (ep_num == ENDP2) { + /* Nothing */ } } -void -usb_cb_rx_ready (uint8_t ep_num) + +static void +stream_input_char (int c) { - if (ep_num == ENDP3) + unsigned int i; + + /* Process DEL, C-U, C-R, and RET as editing command. */ + switch (c) { + case 0x0d: /* Control-M */ + stream_echo_char (0x0d); + stream_echo_char (0x0a); chopstx_mutex_lock (&stream.mtx); if ((stream.flags & FLAG_RECV_AVAIL) == 0) { + memcpy (stream.recv_buf, inputline, inputline_len); + stream.recv_len = inputline_len; stream.flags |= FLAG_RECV_AVAIL; chopstx_cond_signal (&stream.cnd); } chopstx_mutex_unlock (&stream.mtx); + inputline_len = 0; + break; + case 0x12: /* Control-R */ + stream_echo_char ('^'); + stream_echo_char ('R'); + stream_echo_char (0x0d); + stream_echo_char (0x0a); + for (i = 0; i < inputline_len; i++) + stream_echo_char (inputline[i]); + break; + case 0x15: /* Control-U */ + for (i = 0; i < inputline_len; i++) + { + stream_echo_char (0x08); + stream_echo_char (0x20); + stream_echo_char (0x08); + } + inputline_len = 0; + break; + case 0x7f: /* DEL */ + if (inputline_len > 0) + { + stream_echo_char (0x08); + stream_echo_char (0x20); + stream_echo_char (0x08); + inputline_len--; + } + break; + default: + if (inputline_len < sizeof (inputline)) + { + stream_echo_char (c); + inputline[inputline_len++] = c; + } + else + /* Beep */ + stream_echo_char (0x0a); + break; + } +} + +void +usb_cb_rx_ready (uint8_t ep_num) +{ + if (ep_num == ENDP3) + { + int i, r; + + r = usb_lld_rx_data_len (ENDP3); + for (i = 0; i < r; i++) + stream_input_char (recv_buf[i]); + + usb_lld_rx_enable (ENDP3, recv_buf, 64); } } @@ -452,6 +562,7 @@ stream_send (struct stream *st, uint8_t *buf, uint8_t count) r = -1; else { + stream.sending = 1; usb_lld_tx_enable (ENDP1, buf, count); stream.flags |= FLAG_SEND_AVAIL; do @@ -467,6 +578,7 @@ stream_send (struct stream *st, uint8_t *buf, uint8_t count) } while (1); } + stream.sending = 0; chopstx_mutex_unlock (&st->mtx); return r; } @@ -482,14 +594,14 @@ stream_recv (struct stream *st, uint8_t *buf) r = -1; else { - usb_lld_rx_enable (ENDP3, buf, 64); stream.flags &= ~FLAG_RECV_AVAIL; do { chopstx_cond_wait (&st->cnd, &st->mtx); if ((stream.flags & FLAG_RECV_AVAIL)) { - r = usb_lld_rx_data_len (ENDP3); + r = stream.recv_len; + memcpy (buf, stream.recv_buf, r); break; } else if ((stream.flags & FLAG_CONNECTED) == 0) diff --git a/example-fs-bb48/usb_kl27z.c b/example-fs-bb48/usb_kl27z.c index 09a65f7..4e35753 100644 --- a/example-fs-bb48/usb_kl27z.c +++ b/example-fs-bb48/usb_kl27z.c @@ -863,8 +863,8 @@ handle_transaction (uint8_t stat) if ((stat & 0x08) == 0) { dev_p->recv++; - usb_cb_rx_ready (ep_num); ep[ep_num].rx_odd ^= 1; + usb_cb_rx_ready (ep_num); } else { |