diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2016-05-12 18:14:47 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2016-05-12 18:14:47 +0900 |
commit | fabd271196710655a508b8b2727945ddc581d2ae (patch) | |
tree | 48124132a4ba4adcb5d806a68a24a023db701948 /example-cdc | |
parent | 5730641ffdd26c5033ef9d5aaae29b68dee7c2e0 (diff) |
Update example-cdc
Diffstat (limited to 'example-cdc')
-rw-r--r-- | example-cdc/sample.c | 54 | ||||
-rw-r--r-- | example-cdc/sample.ld | 8 | ||||
-rw-r--r-- | example-cdc/stream.h | 4 | ||||
-rw-r--r-- | example-cdc/usb-cdc.c | 140 |
4 files changed, 178 insertions, 28 deletions
diff --git a/example-cdc/sample.c b/example-cdc/sample.c index 7a6b99f..17b7cd5 100644 --- a/example-cdc/sample.c +++ b/example-cdc/sample.c @@ -2,6 +2,7 @@ #include <stdlib.h> #include <string.h> #include <chopstx.h> + #include "sys.h" /* for set_led */ #include "usb_lld.h" #include "stream.h" @@ -10,7 +11,6 @@ static chopstx_mutex_t mtx; static chopstx_cond_t cnd0; static chopstx_cond_t cnd1; - static uint8_t u, v; static uint8_t m; /* 0..100 */ @@ -113,8 +113,10 @@ const size_t __stacksize_blk = (size_t)&__process2_stack_size__; const uint32_t __stackaddr_intr = (uint32_t)&__process3_stack_base__; const size_t __stacksize_intr = (size_t)&__process3_stack_size__; + static char hexchar (uint8_t x) { + x &= 0x0f; if (x <= 0x09) return '0' + x; else if (x <= 0x0f) @@ -124,6 +126,18 @@ static char hexchar (uint8_t x) } +static int +check_recv (void *arg) +{ + struct stream *s = arg; + if ((s->flags & FLAG_CONNECTED) == 0) + return 1; + if ((s->flags & FLAG_RECV_AVAIL)) + return 1; + return 0; +} + + int main (int argc, const char *argv[]) { @@ -163,6 +177,7 @@ main (int argc, const char *argv[]) { uint8_t s[64]; + u = 1; if (stream_wait_connection (st) < 0) { chopstx_usec_wait (1000*1000); @@ -174,7 +189,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++; @@ -184,15 +199,36 @@ main (int argc, const char *argv[]) while (1) { - int size = stream_recv (st, s); - - if (size < 0) - break; - - if (size >= 0) + int size; + uint32_t usec; + struct chx_poll_desc poll_desc; + + poll_desc.type = CHOPSTX_POLL_COND; + poll_desc.c.cond = &st->cnd; + poll_desc.c.mutex = &st->mtx; + poll_desc.c.check = check_recv; + poll_desc.c.arg = st; + + /* With chopstx_poll, we can do timed cond_wait */ + usec = 3000000; /* 3.0 seconds */ + if (chopstx_poll (&usec, 1, &poll_desc)) { - if (stream_send (st, s, size) < 0) + size = stream_recv (st, s + 4); + + if (size < 0) break; + + if (size >= 0) + { + s[0] = hexchar (size >> 4); + s[1] = hexchar (size & 0x0f); + s[2] = ':'; + s[3] = ' '; + s[size + 4] = '\r'; + s[size + 5] = '\n'; + if (stream_send (st, s, size + 6) < 0) + break; + } } u ^= 1; diff --git a/example-cdc/sample.ld b/example-cdc/sample.ld index dd53a0e..9b7eca3 100644 --- a/example-cdc/sample.ld +++ b/example-cdc/sample.ld @@ -2,10 +2,10 @@ * ST32F103 memory setup. */ __main_stack_size__ = 0x0100; /* Exception handlers */ -__process0_stack_size__ = 0x0200; /* Main program */ -__process1_stack_size__ = 0x0200; /* first thread program */ -__process2_stack_size__ = 0x0200; /* second thread program */ -__process3_stack_size__ = 0x0200; /* third thread program */ +__process0_stack_size__ = 0x0400; /* Main program */ +__process1_stack_size__ = 0x0200; /* first thread program */ +__process2_stack_size__ = 0x0200; /* second thread program */ +__process3_stack_size__ = 0x0200; /* third thread program */ MEMORY { diff --git a/example-cdc/stream.h b/example-cdc/stream.h index 15cbe63..dbbfb5f 100644 --- a/example-cdc/stream.h +++ b/example-cdc/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]; /* Not yet used. */ 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-cdc/usb-cdc.c b/example-cdc/usb-cdc.c index 6af47a8..eadeb6e 100644 --- a/example-cdc/usb-cdc.c +++ b/example-cdc/usb-cdc.c @@ -1,9 +1,18 @@ #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 unsigned int recv_len; + +static uint8_t inputline[64]; +static unsigned int inputline_len; + static struct stream stream; #define ENDP0_RXADDR (0x40) @@ -190,6 +199,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); chopstx_mutex_unlock (&stream.mtx); } } @@ -393,36 +404,136 @@ 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) + { + usb_lld_txcpy (send_buf, ENDP1, 0, send_len); + usb_lld_tx_enable (ENDP1, 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; + usb_lld_txcpy (send_buf, ENDP1, 0, send_len); + usb_lld_tx_enable (ENDP1, 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) +{ + uint8_t recv_buf[64]; + + if (ep_num == ENDP3) + { + int i, r; + + r = usb_lld_rx_data_len (ENDP3); + usb_lld_rxcpy (recv_buf, ep_num, 0, r); + for (i = 0; i < r; i++) + stream_input_char (recv_buf[i]); + + usb_lld_rx_enable (ENDP3); } } @@ -456,7 +567,9 @@ stream_send (struct stream *st, uint8_t *buf, uint8_t count) r = -1; else { - usb_lld_write (ENDP1, buf, count); + stream.sending = 1; + usb_lld_txcpy (buf, ENDP1, 0, count); + usb_lld_tx_enable (ENDP1, count); stream.flags |= FLAG_SEND_AVAIL; do { @@ -471,6 +584,7 @@ stream_send (struct stream *st, uint8_t *buf, uint8_t count) } while (1); } + stream.sending = 0; chopstx_mutex_unlock (&st->mtx); return r; } @@ -486,15 +600,13 @@ stream_recv (struct stream *st, uint8_t *buf) r = -1; else { - usb_lld_rx_enable (ENDP3); - stream.flags &= ~FLAG_RECV_AVAIL; - do + while (1) { - chopstx_cond_wait (&st->cnd, &st->mtx); if ((stream.flags & FLAG_RECV_AVAIL)) { - r = usb_lld_rx_data_len (ENDP3); - usb_lld_rxcpy (buf, ENDP3, 0, r); + r = stream.recv_len; + memcpy (buf, stream.recv_buf, r); + stream.flags &= ~FLAG_RECV_AVAIL; break; } else if ((stream.flags & FLAG_CONNECTED) == 0) @@ -502,8 +614,8 @@ stream_recv (struct stream *st, uint8_t *buf) r = -1; break; } + chopstx_cond_wait (&st->cnd, &st->mtx); } - while (1); } chopstx_mutex_unlock (&st->mtx); |