diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2016-06-08 15:43:11 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2016-06-08 15:43:11 +0900 |
commit | d061e6f931f0228158d5a4b72fce501e6219540d (patch) | |
tree | 1794afb33abde21a9b461b16f9ff4039188013ee /example-fs-bb48 | |
parent | 5f1c26ff176ee46f846f74ab361d62305a34c01a (diff) |
USB for FS-BB48
Diffstat (limited to 'example-fs-bb48')
-rw-r--r-- | example-fs-bb48/command.c | 18 | ||||
-rw-r--r-- | example-fs-bb48/sample.c | 4 | ||||
-rw-r--r-- | example-fs-bb48/tty.h | 4 | ||||
-rw-r--r-- | example-fs-bb48/usb-cdc.c | 340 |
4 files changed, 237 insertions, 129 deletions
diff --git a/example-fs-bb48/command.c b/example-fs-bb48/command.c index 70861d8..791854a 100644 --- a/example-fs-bb48/command.c +++ b/example-fs-bb48/command.c @@ -23,7 +23,7 @@ struct command_table static void put_line (struct tty *tty, const char *line) { - tty_send (tty, (uint8_t *)line, strlen (line)); + tty_send (tty, line, strlen (line)); } static const char *help_string = @@ -203,7 +203,7 @@ cmd_mdw (struct tty *tty, const char *line) *s++ = '\r'; *s++ = '\n'; - tty_send (tty, (uint8_t *)output, s - output); + tty_send (tty, output, s - output); } } @@ -326,7 +326,7 @@ cmd_crc32 (struct tty *tty, const char *line) s = compose_hex (string, v); *s++ = '\r'; *s++ = '\n'; - tty_send (tty, (uint8_t *)string, sizeof (string)); + tty_send (tty, string, sizeof (string)); } #endif @@ -369,7 +369,7 @@ cmd_adc (struct tty *tty, const char *line) { *s++ = '\r'; *s++ = '\n'; - tty_send (tty, (uint8_t *)output, s - output); + tty_send (tty, output, s - output); s = output; if (i >= 64) break; @@ -393,14 +393,14 @@ cmd_sysinfo (struct tty *tty, const char *line) *s++ = sys_version[6]; *s++ = '\r'; *s++ = '\n'; - tty_send (tty, (uint8_t *)output, s - output); + tty_send (tty, output, s - output); memcpy (output, "Board ID: ", 10); s = output + 10; s = compose_hex (s, sys_board_id); *s++ = '\r'; *s++ = '\n'; - tty_send (tty, (uint8_t *)output, s - output); + tty_send (tty, output, s - output); memcpy (output, "Board name: ", 12); s = output + 12; @@ -412,7 +412,7 @@ cmd_sysinfo (struct tty *tty, const char *line) *s++ = '\r'; *s++ = '\n'; - tty_send (tty, (uint8_t *)output, s - output); + tty_send (tty, output, s - output); } @@ -470,10 +470,10 @@ cmd_dispatch (struct tty *tty, const char *line) (*command_table[i].handler) (tty, p); else { - uint8_t crlf[] = { '\r', '\n' }; + char crlf[] = { '\r', '\n' }; put_line (tty, "No such command: "); - tty_send (tty, (const uint8_t *)line, n); + tty_send (tty, line, n); tty_send (tty, crlf, sizeof (crlf)); } } diff --git a/example-fs-bb48/sample.c b/example-fs-bb48/sample.c index db8aac5..7d6a3be 100644 --- a/example-fs-bb48/sample.c +++ b/example-fs-bb48/sample.c @@ -151,7 +151,7 @@ main (int argc, const char *argv[]) m = 50; while (1) { - uint8_t s[LINEBUFSIZE]; + char s[LINEBUFSIZE]; connection_loop: u = 1; @@ -175,7 +175,7 @@ main (int argc, const char *argv[]) uint32_t usec; /* Prompt */ - if (tty_send (tty, (uint8_t *)"> ", 2) < 0) + if (tty_send (tty, "> ", 2) < 0) break; usec = 3000000; /* 3.0 seconds */ diff --git a/example-fs-bb48/tty.h b/example-fs-bb48/tty.h index 55e97da..77e7f46 100644 --- a/example-fs-bb48/tty.h +++ b/example-fs-bb48/tty.h @@ -5,5 +5,5 @@ struct tty; struct tty *tty_open (void); void tty_wait_configured (struct tty *tty); void tty_wait_connection (struct tty *tty); -int tty_send (struct tty *tty, const uint8_t *buf, int count); -int tty_recv (struct tty *tty, uint8_t *buf, uint32_t *timeout); +int tty_send (struct tty *tty, const char *buf, int count); +int tty_recv (struct tty *tty, char *buf, uint32_t *timeout); diff --git a/example-fs-bb48/usb-cdc.c b/example-fs-bb48/usb-cdc.c index 39c589a..119e6ae 100644 --- a/example-fs-bb48/usb-cdc.c +++ b/example-fs-bb48/usb-cdc.c @@ -31,7 +31,7 @@ static const struct line_coding line_coding0 = { * * In that case, add argument to TTY_OPEN function and * modify TTY_GET function to get the TTY structure. Functions which - * directy accesses TTY0 (usb_cb_device_reset and usb_cb_handle_event) + * directy accesses TTY0 (usb_device_reset and usb_set_configuration) * should be modified, too. * * Modification of TTY_MAIN thread will be also needed to echo back @@ -231,13 +231,13 @@ static const uint8_t vcom_string3[28] = { #define NUM_INTERFACES 2 -void -usb_cb_device_reset (void) +static void +usb_device_reset (struct usb_dev *dev) { - usb_lld_reset (VCOM_FEATURE_BUS_POWERED); + usb_lld_reset (dev, VCOM_FEATURE_BUS_POWERED); /* Initialize Endpoint 0 */ - usb_lld_setup_endp (ENDP0, 1, 1); + usb_lld_setup_endp (dev, ENDP0, 1, 1); chopstx_mutex_lock (&tty0.mtx); tty0.inputline_len = 0; @@ -253,13 +253,15 @@ usb_cb_device_reset (void) #define CDC_CTRL_DTR 0x0001 -void -usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg) +static void +usb_ctrl_write_finish (struct usb_dev *dev) { - uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); + struct device_req *arg = &dev->dev_req; + uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT); if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0 - && USB_SETUP_SET (req) && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE) + && USB_SETUP_SET (arg->type) + && arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE) { struct tty *t = tty_get (arg->index, 0); @@ -274,58 +276,64 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg) static int -vcom_port_data_setup (uint8_t req, uint8_t req_no, struct req_args *arg) +vcom_port_data_setup (struct usb_dev *dev) { - if (USB_SETUP_GET (req)) + struct device_req *arg = &dev->dev_req; + + if (USB_SETUP_GET (arg->type)) { struct tty *t = tty_get (arg->index, 0); - if (req_no == USB_CDC_REQ_GET_LINE_CODING) - return usb_lld_reply_request (&t->line_coding, - sizeof (struct line_coding), arg); + if (arg->request == USB_CDC_REQ_GET_LINE_CODING) + return usb_lld_reply_request (dev, &t->line_coding, + sizeof (struct line_coding)); } else /* USB_SETUP_SET (req) */ { - if (req_no == USB_CDC_REQ_SET_LINE_CODING + if (arg->request == USB_CDC_REQ_SET_LINE_CODING && arg->len == sizeof (struct line_coding)) { struct tty *t = tty_get (arg->index, 0); - usb_lld_set_data_to_recv (&t->line_coding, - sizeof (struct line_coding)); - return USB_SUCCESS; + return usb_lld_set_data_to_recv (dev, &t->line_coding, + sizeof (struct line_coding)); } - else if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE) - return USB_SUCCESS; + else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE) + return 0; } - return USB_UNSUPPORT; + return -1; } -int -usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg) +static int +usb_setup (struct usb_dev *dev) { - uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); + struct device_req *arg = &dev->dev_req; + uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT); if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0) - return vcom_port_data_setup (req, req_no, arg); + return vcom_port_data_setup (dev); - return USB_UNSUPPORT; + return -1; } -int -usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, - struct req_args *arg) +static int +usb_get_descriptor (struct usb_dev *dev) { + struct device_req *arg = &dev->dev_req; + uint8_t rcp = arg->type & RECIPIENT; + uint8_t desc_type = (arg->value >> 8); + uint8_t desc_index = (arg->value & 0xff); + if (rcp != DEVICE_RECIPIENT) - return USB_UNSUPPORT; + return -1; if (desc_type == DEVICE_DESCRIPTOR) - return usb_lld_reply_request (vcom_device_desc, sizeof (vcom_device_desc), - arg); + return usb_lld_reply_request (dev, + vcom_device_desc, sizeof (vcom_device_desc)); else if (desc_type == CONFIG_DESCRIPTOR) - return usb_lld_reply_request (vcom_config_desc, sizeof (vcom_config_desc), - arg); + return usb_lld_reply_request (dev, + vcom_config_desc, sizeof (vcom_config_desc)); else if (desc_type == STRING_DESCRIPTOR) { const uint8_t *str; @@ -350,22 +358,23 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, size = sizeof (vcom_string3); break; default: - return USB_UNSUPPORT; + return -1; } - return usb_lld_reply_request (str, size, arg); + return usb_lld_reply_request (dev, str, size); } - return USB_UNSUPPORT; + return -1; } static void -vcom_setup_endpoints_for_interface (uint16_t interface, int stop) +vcom_setup_endpoints_for_interface (struct usb_dev *dev, + uint16_t interface, int stop) { if (interface == 0) { if (!stop) - usb_lld_setup_endp (ENDP2, 0, 1); + usb_lld_setup_endp (dev, ENDP2, 0, 1); else usb_lld_stall (ENDP2); } @@ -373,8 +382,8 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop) { if (!stop) { - usb_lld_setup_endp (ENDP1, 0, 1); - usb_lld_setup_endp (ENDP3, 1, 0); + usb_lld_setup_endp (dev, ENDP1, 0, 1); + usb_lld_setup_endp (dev, ENDP3, 1, 0); /* Start with no data receiving (ENDP3 not enabled)*/ } else @@ -385,83 +394,84 @@ vcom_setup_endpoints_for_interface (uint16_t interface, int stop) } } -int -usb_cb_handle_event (uint8_t event_type, uint16_t value) +static int +usb_set_configuration (struct usb_dev *dev) { int i; uint8_t current_conf; - switch (event_type) + current_conf = usb_lld_current_configuration (dev); + if (current_conf == 0) { - case USB_EVENT_ADDRESS: + if (dev->dev_req.value != 1) + return -1; + + usb_lld_set_configuration (dev, 1); + for (i = 0; i < NUM_INTERFACES; i++) + vcom_setup_endpoints_for_interface (dev, i, 0); + chopstx_mutex_lock (&tty0.mtx); + tty0.device_state = CONFIGURED; + chopstx_cond_signal (&tty0.cnd); + chopstx_mutex_unlock (&tty0.mtx); + } + else if (current_conf != dev->dev_req.value) + { + if (dev->dev_req.value != 0) + return -1; + + usb_lld_set_configuration (dev, 0); + for (i = 0; i < NUM_INTERFACES; i++) + vcom_setup_endpoints_for_interface (dev, i, 1); chopstx_mutex_lock (&tty0.mtx); tty0.device_state = ADDRESSED; + chopstx_cond_signal (&tty0.cnd); chopstx_mutex_unlock (&tty0.mtx); - return USB_SUCCESS; - case USB_EVENT_CONFIG: - current_conf = usb_lld_current_configuration (); - if (current_conf == 0) - { - if (value != 1) - return USB_UNSUPPORT; - - usb_lld_set_configuration (1); - for (i = 0; i < NUM_INTERFACES; i++) - vcom_setup_endpoints_for_interface (i, 0); - chopstx_mutex_lock (&tty0.mtx); - tty0.device_state = CONFIGURED; - chopstx_mutex_unlock (&tty0.mtx); - } - else if (current_conf != value) - { - if (value != 0) - return USB_UNSUPPORT; - - usb_lld_set_configuration (0); - for (i = 0; i < NUM_INTERFACES; i++) - vcom_setup_endpoints_for_interface (i, 1); - chopstx_mutex_lock (&tty0.mtx); - tty0.device_state = ADDRESSED; - chopstx_mutex_unlock (&tty0.mtx); - } - /* Do nothing when current_conf == value */ - return USB_SUCCESS; - default: - break; } - return USB_UNSUPPORT; + return 0; } -int -usb_cb_interface (uint8_t cmd, struct req_args *arg) +static int +usb_set_interface (struct usb_dev *dev) { - const uint8_t zero = 0; - uint16_t interface = arg->index; - uint16_t alt = arg->value; + uint16_t interface = dev->dev_req.index; + uint16_t alt = dev->dev_req.value; if (interface >= NUM_INTERFACES) - return USB_UNSUPPORT; + return -1; - switch (cmd) + if (alt != 0) + return -1; + else { - case USB_SET_INTERFACE: - if (alt != 0) - return USB_UNSUPPORT; - else - { - vcom_setup_endpoints_for_interface (interface, 0); - return USB_SUCCESS; - } + vcom_setup_endpoints_for_interface (dev, interface, 0); + return 0; + } +} + +static int +usb_get_interface (struct usb_dev *dev) +{ + const uint8_t zero = 0; + uint16_t interface = dev->dev_req.index; - case USB_GET_INTERFACE: - return usb_lld_reply_request (&zero, 1, arg); + if (interface >= NUM_INTERFACES) + return -1; - default: - case USB_QUERY_INTERFACE: - return USB_SUCCESS; - } + /* We don't have alternate interface, so, always return 0. */ + return usb_lld_reply_request (dev, &zero, 1); +} +static int +usb_get_status_interface (struct usb_dev *dev) +{ + const uint16_t status_info = 0; + uint16_t interface = dev->dev_req.index; + + if (interface >= NUM_INTERFACES) + return -1; + + return usb_lld_reply_request (dev, &status_info, 2); } @@ -511,8 +521,8 @@ tty_echo_char (struct tty *t, int c) put_char_to_ringbuffer (t, c); } -void -usb_cb_tx_done (uint8_t ep_num, uint32_t len) +static void +usb_tx_done (uint8_t ep_num, uint16_t len) { struct tty *t = tty_get (-1, ep_num); @@ -594,17 +604,16 @@ tty_input_char (struct tty *t, int c) return r; } -void -usb_cb_rx_ready (uint8_t ep_num) +static void +usb_rx_ready (uint8_t ep_num, uint16_t len) { struct tty *t = tty_get (-1, ep_num); if (ep_num == ENDP3) { - int i, r; + int i; - r = usb_lld_rx_data_len (ENDP3); - for (i = 0; i < r; i++) + for (i = 0; i < len; i++) if (tty_input_char (t, t->recv_buf0[i])) break; @@ -646,6 +655,8 @@ static void * tty_main (void *arg) { struct tty *t = arg; + struct usb_dev dev; + int e; #if defined(OLDER_SYS_H) /* @@ -654,9 +665,9 @@ tty_main (void *arg) * * When USB interrupt occurs between usb_lld_init (which assumes * ISR) and chopstx_claim_irq (which clears pending interrupt), - * invocation of usb_interrupt_handler won't occur. + * invocation of usb_lld_event_handler won't occur. * - * Calling usb_interrupt_handler is no harm even if there were no + * Calling usb_lld_event_handler is no harm even if there were no * interrupts, thus, we call it unconditionally here, just in case * if there is a request. * @@ -665,19 +676,117 @@ tty_main (void *arg) * chopstx_claim_irq after usb_lld_init overrides that. * */ - usb_lld_init (VCOM_FEATURE_BUS_POWERED); + usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); chopstx_claim_irq (&usb_intr, INTR_REQ_USB); - usb_interrupt_handler (); + goto event_handle; #else chopstx_claim_irq (&usb_intr, INTR_REQ_USB); - usb_lld_init (VCOM_FEATURE_BUS_POWERED); + usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED); #endif while (1) { chopstx_poll (NULL, 1, &usb_intr); if (usb_intr.ready) - usb_interrupt_handler (); + { + uint8_t ep_num; +#if defined(OLDER_SYS_H) + event_handle: +#endif + /* + * When interrupt is detected, call usb_lld_event_handler. + * The event may be one of following: + * (1) Transfer to endpoint (bulk or interrupt) + * In this case EP_NUM is encoded in the variable E. + * (2) "NONE" event: some trasfer was done, but all was + * done by lower layer, no other work is needed in + * upper layer. + * (3) Device events: Reset or Suspend + * (4) Device requests to the endpoint zero. + * + */ + e = usb_lld_event_handler (&dev); + ep_num = USB_EVENT_ENDP (e); + + if (ep_num != 0) + { + if (USB_EVENT_TXRX (e)) + usb_tx_done (ep_num, USB_EVENT_LEN (e)); + else + usb_rx_ready (ep_num, USB_EVENT_LEN (e)); + } + else + switch (USB_EVENT_ID (e)) + { + case USB_EVENT_DEVICE_RESET: + usb_device_reset (&dev); + continue; + + case USB_EVENT_GET_DESCRIPTOR: + if (usb_get_descriptor (&dev) < 0) + usb_lld_ctrl_error (&dev); + continue; + + /* The addres is assigned to the device. We don't + * need to do anything for this actually, but in this + * application, we maintain the USB status of the + * device. Usually, just "continue" as EVENT_NONE is + * OK. + */ + case USB_EVENT_DEVICE_ADDRESSED: + chopstx_mutex_lock (&tty0.mtx); + tty0.device_state = ADDRESSED; + chopstx_cond_signal (&tty0.cnd); + chopstx_mutex_unlock (&tty0.mtx); + continue; + + case USB_EVENT_SET_CONFIGURATION: + if (usb_set_configuration (&dev) < 0) + usb_lld_ctrl_error (&dev); + else + usb_lld_ctrl_good (&dev); + continue; + + case USB_EVENT_SET_INTERFACE: + if (usb_set_interface (&dev) < 0) + usb_lld_ctrl_error (&dev); + else + usb_lld_ctrl_good (&dev); + continue; + + /* Non standard device request. */ + case USB_EVENT_CTRL_REQUEST: + if (usb_setup (&dev) < 0) + usb_lld_ctrl_error (&dev); + else + usb_lld_ctrl_good (&dev); + continue; + + /* Control WRITE transfer finished. */ + case USB_EVENT_CTRL_WRITE_FINISH: + usb_ctrl_write_finish (&dev); + continue; + + case USB_EVENT_GET_STATUS_INTERFACE: + if (usb_get_status_interface (&dev) < 0) + usb_lld_ctrl_error (&dev); + continue; + + case USB_EVENT_GET_INTERFACE: + if (usb_get_interface (&dev) < 0) + usb_lld_ctrl_error (&dev); + continue; + + case USB_EVENT_NONE: + case USB_EVENT_SET_FEATURE_DEVICE: + case USB_EVENT_SET_FEATURE_ENDPOINT: + case USB_EVENT_CLEAR_FEATURE_DEVICE: + case USB_EVENT_CLEAR_FEATURE_ENDPOINT: + case USB_EVENT_DEVICE_SUSPEND: + default: + continue; + } + } chopstx_mutex_lock (&t->mtx); if (t->device_state == CONFIGURED && t->flag_connected @@ -720,8 +829,7 @@ tty_wait_connection (struct tty *t) t->flag_input_avail = 0; t->send_head = t->send_tail = 0; t->inputline_len = 0; - /* Accept input for line */ - usb_lld_rx_enable_buf (ENDP3, t->recv_buf0, 64); + usb_lld_rx_enable_buf (ENDP3, t->recv_buf0, 64); /* Accept input for line */ chopstx_mutex_unlock (&t->mtx); } @@ -738,10 +846,10 @@ check_tx (struct tty *t) } int -tty_send (struct tty *t, const uint8_t *buf, int len) +tty_send (struct tty *t, const char *buf, int len) { int r; - const uint8_t *p; + const char *p; int count; p = buf; @@ -800,7 +908,7 @@ check_rx (void *arg) * */ int -tty_recv (struct tty *t, uint8_t *buf, uint32_t *timeout) +tty_recv (struct tty *t, char *buf, uint32_t *timeout) { int r; chopstx_poll_cond_t poll_desc; |