Update USB and Chopstx
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 26 May 2016 04:09:34 +0000 (13:09 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 26 May 2016 04:24:28 +0000 (13:24 +0900)
ChangeLog
README
chopstx
src/adc.h
src/configure
src/main.c
src/neug.c
src/sys.c
src/usb_lld.h
src/usb_stm32f103.c

index b118eb4..1c58963 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2016-05-26  NIIBE Yutaka  <gniibe@fsij.org>
+
+       * chopstx: Update.
+       * src/adc.h: Update from Gnuk.
+       * src/neug.c: Update from Gnuk.
+       * src/usb_stm32f103.c: Update from Chopstx.
+       * src/usb_lld.h: Update from Chopstx.
+       * src/sys.c: Update from Chopstx.
+       * src/configure: Follow the change of USB API.
+       * src/main.c (usb_cb_device_reset, usb_cb_ctrl_write_finish)
+       (vcom_port_data_setup, usb_cb_setup, usb_cb_get_descriptor)
+       (usb_cb_interface, usb_intr): Follow the change of USB API.
+       (VCOM_FEATURE_BUS_POWERED): New.
+       (usb_cb_handle_event): Clean up.
+       (usb_cb_tx_done, usb_cb_rx_ready): New.
+       (main): Use chopstx_poll.
+
 2016-02-05   Niibe Yutaka  <gniibe@fsij.org>
 
        * src/configure: Add submodule check suggested by Elliott
diff --git a/README b/README
index 4ed98e1..d4d3786 100644 (file)
--- a/README
+++ b/README
@@ -269,7 +269,7 @@ If your device is configured with Fraucheky, you can invoke Fraucheky
 from NeuG by setting the unusual sequence of configurations:
 
   $ stty -F /dev/ttyACM0 ispeed 110 ospeed 110
-  $ stty -F /dev/ttyACM0 speed 115200 ospeed 115200
+  $ stty -F /dev/ttyACM0 ispeed 115200 ospeed 115200
 
 
 Structure of NeuG
diff --git a/chopstx b/chopstx
index a30a069..91823d0 160000 (submodule)
--- a/chopstx
+++ b/chopstx
@@ -1 +1 @@
-Subproject commit a30a069ed8e75f14b520b407b07a3f137b87ef1c
+Subproject commit 91823d0fc141232cb7672de7432e05126078b574
index 67367b0..54e1f4e 100644 (file)
--- a/src/adc.h
+++ b/src/adc.h
@@ -1,15 +1,7 @@
-extern chopstx_mutex_t adc_mtx;
-extern chopstx_cond_t adc_cond;
-extern int adc_waiting;
-extern int adc_data_available;
-
 void adc_init (void);
 void adc_start (void);
 void adc_stop (void);
 
-#define ADC_SAMPLE_MODE 0
-#define ADC_CRC32_MODE  1
-
 extern uint32_t adc_buf[64];
 
 void adc_start_conversion (int offset, int count);
index fc17f45..4d8bfdb 100755 (executable)
@@ -236,14 +236,14 @@ output_vendor_product_serial_strings () {
 
   echo "static const uint8_t ${prefix}string_vendor[] = {"
   echo "  ${#VENDOR}*2+2,                      /* bLength */"
-  echo "  USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */"
+  echo "  STRING_DESCRIPTOR,           /* bDescriptorType */"
   echo "  /* Manufacturer: \"$VENDOR\" */"
   echo $VENDOR | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/  /" -e "/^  ./s/ $//p"
   echo '};'
   echo
   echo "static const uint8_t ${prefix}string_product[] = {"
   echo "  ${#PRODUCT}*2+2,                     /* bLength */"
-  echo "  USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */"
+  echo "  STRING_DESCRIPTOR,           /* bDescriptorType */"
   echo "  /* Product name: \"$PRODUCT\" */"
   echo $PRODUCT | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/  /" -e "/^  ./s/ $//p"
   echo '};'
@@ -252,7 +252,7 @@ output_vendor_product_serial_strings () {
   echo
   echo "static uint8_t ${prefix}string_serial[] = {"
   echo "  ${#SERIALNO}*2+2+16,                 /* bLength */"
-  echo "  USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */"
+  echo "  STRING_DESCRIPTOR,           /* bDescriptorType */"
   echo "  /* Serial number: \"$SERIALNO\" */"
   echo $SERIALNO | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/  /" -e "/^  ./s/ $//p"
   echo "  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
@@ -261,14 +261,14 @@ output_vendor_product_serial_strings () {
   echo
   echo "static const uint8_t ${prefix}revision_detail[] = {"
   echo "  ${#REVISION}*2+2,                    /* bLength */"
-  echo "  USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */"
+  echo "  STRING_DESCRIPTOR,           /* bDescriptorType */"
   echo "  /* revision detail: \"$REVISION\" */"
   echo $REVISION | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/  /" -e "/^  ./s/ $//p"
   echo '};'
   echo
   echo "static const uint8_t ${prefix}config_options[] = {"
   echo "  ${#CONFIG}*2+2,                      /* bLength */"
-  echo "  USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */"
+  echo "  STRING_DESCRIPTOR,           /* bDescriptorType */"
   echo "  /* configure options: \"$CONFIG\" */"
   echo $CONFIG | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/  /" -e "/^  ./s/ $//p"
   echo '};'
index edf2871..6602f88 100644 (file)
@@ -2,7 +2,7 @@
  * main.c - main routine of neug
  *
  * Main routine:
- * Copyright (C) 2011, 2012, 2013, 2015
+ * Copyright (C) 2011, 2012, 2013, 2015, 2016
  *              Free Software Initiative of Japan
  * Author: NIIBE Yutaka <gniibe@fsij.org>
  *
@@ -50,16 +50,12 @@ static uint8_t running_neug;
 #endif
 
 static chopstx_mutex_t usb_mtx;
-static chopstx_cond_t cnd_usb;
+static chopstx_cond_t usb_cnd;
 static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
 static uint8_t fsij_device_state = FSIJ_DEVICE_RUNNING;
 static uint8_t connected;
-static uint32_t wait_usb_connection; /* Timer variable.  */
 
 
-extern uint8_t __process0_stack_end__;
-static chopstx_t main_thd = (uint32_t)(&__process0_stack_end__ - 60);
-
 #define ENDP0_RXADDR        (0x40)
 #define ENDP0_TXADDR        (0x80)
 #define ENDP1_TXADDR        (0xc0)
@@ -74,7 +70,7 @@ static chopstx_t main_thd = (uint32_t)(&__process0_stack_end__ - 60);
 /* USB Device Descriptor */
 static const uint8_t vcom_device_desc[18] = {
   18,   /* bLength */
-  USB_DEVICE_DESCRIPTOR_TYPE,  /* bDescriptorType */
+  DEVICE_DESCRIPTOR,           /* bDescriptorType */
   0x10, 0x01,                  /* bcdUSB = 1.1 */
   0x02,                                /* bDeviceClass (CDC).              */
   0x00,                                /* bDeviceSubClass.                 */
@@ -87,20 +83,22 @@ static const uint8_t vcom_device_desc[18] = {
   1                            /* bNumConfigurations.              */
 };
 
+#define VCOM_FEATURE_BUS_POWERED       0x80
+
 /* Configuration Descriptor tree for a CDC.*/
 static const uint8_t vcom_config_desc[67] = {
   9,
-  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
+  CONFIG_DESCRIPTOR,            /* bDescriptorType: Configuration   */
   /* Configuration Descriptor.*/
   67, 0x00,                    /* wTotalLength.                    */
   0x02,                                /* bNumInterfaces.                  */
   0x01,                                /* bConfigurationValue.             */
   0,                           /* iConfiguration.                  */
-  0x80,                                /* bmAttributes (bus powered).      */
+  VCOM_FEATURE_BUS_POWERED,    /* bmAttributes.                    */
   50,                          /* bMaxPower (100mA).               */
   /* Interface Descriptor.*/
   9,
-  USB_INTERFACE_DESCRIPTOR_TYPE,
+  INTERFACE_DESCRIPTOR,
   0x00,                   /* bInterfaceNumber.                */
   0x00,                   /* bAlternateSetting.               */
   0x01,                   /* bNumEndpoints.                   */
@@ -139,14 +137,14 @@ static const uint8_t vcom_config_desc[67] = {
   0x01,         /* bSlaveInterface0 (Data Class Interface).  */
   /* Endpoint 2 Descriptor.*/
   7,
-  USB_ENDPOINT_DESCRIPTOR_TYPE,
+  ENDPOINT_DESCRIPTOR,
   ENDP2|0x80,    /* bEndpointAddress.    */
   0x03,          /* bmAttributes (Interrupt).        */
   0x08, 0x00,   /* wMaxPacketSize.                  */
   0xFF,                 /* bInterval.                       */
   /* Interface Descriptor.*/
   9,
-  USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
+  INTERFACE_DESCRIPTOR,          /* bDescriptorType: */
   0x01,          /* bInterfaceNumber.                */
   0x00,          /* bAlternateSetting.               */
   0x02,          /* bNumEndpoints.                   */
@@ -156,14 +154,14 @@ static const uint8_t vcom_config_desc[67] = {
   0x00,                 /* iInterface.                      */
   /* Endpoint 3 Descriptor.*/
   7,
-  USB_ENDPOINT_DESCRIPTOR_TYPE,        /* bDescriptorType: Endpoint */
+  ENDPOINT_DESCRIPTOR,         /* bDescriptorType: Endpoint */
   ENDP3,    /* bEndpointAddress. */
   0x02,                                /* bmAttributes (Bulk).             */
   0x40, 0x00,                  /* wMaxPacketSize.                  */
   0x00,                                /* bInterval.                       */
   /* Endpoint 1 Descriptor.*/
   7,
-  USB_ENDPOINT_DESCRIPTOR_TYPE,        /* bDescriptorType: Endpoint */
+  ENDPOINT_DESCRIPTOR,         /* bDescriptorType: Endpoint */
   ENDP1|0x80,                  /* bEndpointAddress. */
   0x02,                                /* bmAttributes (Bulk).             */
   0x40, 0x00,                  /* wMaxPacketSize.                  */
@@ -176,7 +174,7 @@ static const uint8_t vcom_config_desc[67] = {
  */
 static const uint8_t vcom_string0[4] = {
   4,                           /* bLength */
-  USB_STRING_DESCRIPTOR_TYPE,
+  STRING_DESCRIPTOR,
   0x09, 0x04                   /* LangID = 0x0409: US-English */
 };
 
@@ -189,10 +187,10 @@ extern void fraucheky_main (void);
 
 extern void fraucheky_setup_endpoints_for_interface (int stop);
 extern int fraucheky_setup (uint8_t req, uint8_t req_no,
-                           struct control_info *detail);
+                           struct req_args *detail);
 extern int fraucheky_get_descriptor (uint8_t rcp, uint8_t desc_type,
                                     uint8_t desc_index,
-                                    struct control_info *detail);
+                                    struct req_args *detail);
 #endif
 
 #define NUM_INTERFACES 2
@@ -202,13 +200,7 @@ usb_cb_device_reset (void)
 {
   int i;
 
-  /* Set DEVICE as not configured.  */
-  usb_lld_set_configuration (0);
-
-  /* Current Feature initialization.  */
-  usb_lld_set_feature (vcom_config_desc[7]);
-
-  usb_lld_reset ();
+  usb_lld_reset (VCOM_FEATURE_BUS_POWERED);
 
   /* Initialize Endpoint 0.  */
   usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
@@ -221,8 +213,7 @@ usb_cb_device_reset (void)
   chopstx_mutex_lock (&usb_mtx);
   bDeviceState = ATTACHED;
   connected = 0;
-  if (!wait_usb_connection)
-    chopstx_cond_signal (&cnd_usb);
+  chopstx_cond_signal (&usb_cnd);
   chopstx_mutex_unlock (&usb_mtx);
 }
 
@@ -307,7 +298,7 @@ static struct line_coding line_coding = {
 #define CDC_CTRL_DTR            0x0001
 
 void
-usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
+usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg)
 {
   uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
 
@@ -334,27 +325,20 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
            {
              chopstx_mutex_lock (&usb_mtx);
              fsij_device_state = FSIJ_DEVICE_NEUG_EXIT_REQUESTED;
-             chopstx_wakeup_usec_wait (main_thd);
-             chopstx_cond_signal (&cnd_usb);
+             chopstx_cond_signal (&usb_cnd);
              chopstx_mutex_unlock (&usb_mtx);
            }
        }
     }
-  else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
+  else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0
           && USB_SETUP_SET (req))
     {
       if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
        {
          /* Open/close the connection.  */
          chopstx_mutex_lock (&usb_mtx);
-         connected = (value & CDC_CTRL_DTR)? 1 : 0;
-         if (wait_usb_connection)
-           {                   /* It is waiting a connection.  */
-             if (connected)    /* It's now connected.  */
-               chopstx_wakeup_usec_wait (main_thd);
-           }
-         else
-           chopstx_cond_signal (&cnd_usb);
+         connected = (arg->value & CDC_CTRL_DTR)? 1 : 0;
+         chopstx_cond_signal (&usb_cnd);
          chopstx_mutex_unlock (&usb_mtx);
        }
 #ifdef FRAUCHEKY_SUPPORT
@@ -364,8 +348,7 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
          if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
            {
              fsij_device_state = FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED;
-             chopstx_wakeup_usec_wait (main_thd);
-             chopstx_cond_signal (&cnd_usb);
+             chopstx_cond_signal (&usb_cnd);
            }
          else if (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
            fsij_device_state = FSIJ_DEVICE_RUNNING;
@@ -377,17 +360,17 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
 
 
 static int
-vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
+vcom_port_data_setup (uint8_t req, uint8_t req_no, struct req_args *arg)
 {
   if (USB_SETUP_GET (req))
     {
       if (req_no == USB_CDC_REQ_GET_LINE_CODING)
-       return usb_lld_reply_request (&line_coding, sizeof(line_coding), detail);
+       return usb_lld_reply_request (&line_coding, sizeof(line_coding), arg);
     }
   else  /* USB_SETUP_SET (req) */
     {
       if (req_no == USB_CDC_REQ_SET_LINE_CODING
-         && detail->len == sizeof (line_coding))
+         && arg->len == sizeof (line_coding))
        {
          usb_lld_set_data_to_recv (&line_coding, sizeof (line_coding));
          return USB_SUCCESS;
@@ -400,7 +383,7 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
 }
 
 int
-usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
+usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg)
 {
   uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
 
@@ -417,27 +400,27 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
                  return USB_UNSUPPORT;
                }
              chopstx_mutex_unlock (&usb_mtx);
-             usb_lld_reply_request (mem_info, sizeof (mem_info), detail);
+             usb_lld_reply_request (mem_info, sizeof (mem_info), arg);
              return USB_SUCCESS;
            }
          else if (req_no == USB_NEUG_GET_INFO)
            {
-             if (detail->index == 0)
-               usb_lld_reply_request (&neug_mode, sizeof (uint8_t), detail);
-             else if (detail->index == 1)
-               usb_lld_reply_request (&neug_err_cnt, sizeof (uint16_t), detail);
-             else if (detail->index == 2)
-               usb_lld_reply_request (&neug_err_cnt_rc, sizeof (uint16_t), detail);
-             else if (detail->index == 3)
-               usb_lld_reply_request (&neug_err_cnt_p64, sizeof (uint16_t), detail);
-             else if (detail->index == 4)
-               usb_lld_reply_request (&neug_err_cnt_p4k, sizeof (uint16_t), detail);
-             else if (detail->index == 5)
-               usb_lld_reply_request (&neug_rc_max, sizeof (uint16_t), detail);
-             else if (detail->index == 6)
-               usb_lld_reply_request (&neug_p64_max, sizeof (uint16_t), detail);
-             else if (detail->index == 7)
-               usb_lld_reply_request (&neug_p4k_max, sizeof (uint16_t), detail);
+             if (arg->index == 0)
+               usb_lld_reply_request (&neug_mode, sizeof (uint8_t), arg);
+             else if (arg->index == 1)
+               usb_lld_reply_request (&neug_err_cnt, sizeof (uint16_t), arg);
+             else if (arg->index == 2)
+               usb_lld_reply_request (&neug_err_cnt_rc, sizeof (uint16_t), arg);
+             else if (arg->index == 3)
+               usb_lld_reply_request (&neug_err_cnt_p64, sizeof (uint16_t), arg);
+             else if (arg->index == 4)
+               usb_lld_reply_request (&neug_err_cnt_p4k, sizeof (uint16_t), arg);
+             else if (arg->index == 5)
+               usb_lld_reply_request (&neug_rc_max, sizeof (uint16_t), arg);
+             else if (arg->index == 6)
+               usb_lld_reply_request (&neug_p64_max, sizeof (uint16_t), arg);
+             else if (arg->index == 7)
+               usb_lld_reply_request (&neug_p4k_max, sizeof (uint16_t), arg);
              else
                return USB_UNSUPPORT;
 
@@ -446,7 +429,7 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
        }
       else /* SETUP_SET */
        {
-         uint8_t *addr = (uint8_t *)(0x20000000 + detail->value * 0x100 + detail->index);
+         uint8_t *addr = (uint8_t *)(0x20000000 + arg->value * 0x100 + arg->index);
 
          if (req_no == USB_FSIJ_DOWNLOAD)
            {
@@ -458,16 +441,16 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
                }
              chopstx_mutex_unlock (&usb_mtx);
 
-             if (addr < &_regnual_start || addr + detail->len > &__heap_end__)
+             if (addr < &_regnual_start || addr + arg->len > &__heap_end__)
                return USB_UNSUPPORT;
 
-             if (detail->index + detail->len < 256)
-               memset (addr + detail->index + detail->len, 0, 256 - (detail->index + detail->len));
+             if (arg->index + arg->len < 256)
+               memset (addr + arg->index + arg->len, 0, 256 - (arg->index + arg->len));
 
-             usb_lld_set_data_to_recv (addr, detail->len);
+             usb_lld_set_data_to_recv (addr, arg->len);
              return USB_SUCCESS;
            }
-         else if (req_no == USB_FSIJ_EXEC && detail->len == 0)
+         else if (req_no == USB_FSIJ_EXEC && arg->len == 0)
            {
              chopstx_mutex_lock (&usb_mtx);
              if (fsij_device_state != FSIJ_DEVICE_EXITED)
@@ -482,13 +465,13 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
 
              return download_check_crc32 ((uint32_t *)addr);
            }
-         else if (req_no == USB_NEUG_SET_PASSWD && detail->len <= 32)
+         else if (req_no == USB_NEUG_SET_PASSWD && arg->len <= 32)
            {
-             usbbuf[0] = detail->len;
-             usb_lld_set_data_to_recv (usbbuf + 1, detail->len);
+             usbbuf[0] = arg->len;
+             usb_lld_set_data_to_recv (usbbuf + 1, arg->len);
              return USB_SUCCESS;
            }
-         else if (req_no == USB_NEUG_EXIT && detail->len <= 32)
+         else if (req_no == USB_NEUG_EXIT && arg->len <= 32)
            {
              chopstx_mutex_lock (&usb_mtx);
              if (fsij_device_state != FSIJ_DEVICE_RUNNING)
@@ -498,22 +481,22 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
                }
              chopstx_mutex_unlock (&usb_mtx);
 
-             usbbuf[0] = detail->len;
-             usb_lld_set_data_to_recv (usbbuf + 1, detail->len);
+             usbbuf[0] = arg->len;
+             usb_lld_set_data_to_recv (usbbuf + 1, arg->len);
              return USB_SUCCESS;
            }
        }
     }
   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
-          && detail->index == 0)
+          && arg->index == 0)
     {
 #ifdef FRAUCHEKY_SUPPORT
       if (running_neug)
-       return vcom_port_data_setup (req, req_no, detail);
+       return vcom_port_data_setup (req, req_no, arg);
       else
-       fraucheky_setup (req, req_no, detail);
+       fraucheky_setup (req, req_no, arg);
 #else
-      return vcom_port_data_setup (req, req_no, detail);
+      return vcom_port_data_setup (req, req_no, arg);
 #endif
     }
 
@@ -522,11 +505,11 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
 
 int
 usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
-                      struct control_info *detail)
+                      struct req_args *arg)
 {
 #ifdef FRAUCHEKY_SUPPORT
   if (!running_neug)
-    return fraucheky_get_descriptor (rcp, desc_type, desc_index, detail);
+    return fraucheky_get_descriptor (rcp, desc_type, desc_index, arg);
 #endif
 
   if (rcp != DEVICE_RECIPIENT)
@@ -534,10 +517,10 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
 
   if (desc_type == DEVICE_DESCRIPTOR)
     return usb_lld_reply_request (vcom_device_desc, sizeof (vcom_device_desc),
-                                 detail);
+                                 arg);
   else if (desc_type == CONFIG_DESCRIPTOR)
     return usb_lld_reply_request (vcom_config_desc, sizeof (vcom_config_desc),
-                                 detail);
+                                 arg);
   else if (desc_type == STRING_DESCRIPTOR)
     {
       const uint8_t *str;
@@ -586,7 +569,7 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
                usbbuf[i*2+3] = 0;
              }
            usbbuf[0] = i*2 + 2;
-           usbbuf[1] = USB_STRING_DESCRIPTOR_TYPE;
+           usbbuf[1] = STRING_DESCRIPTOR;
            size = i*2 + 2;
          }
          break;
@@ -594,7 +577,7 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
          return USB_UNSUPPORT;
        }
 
-      return usb_lld_reply_request (str, size, detail);
+      return usb_lld_reply_request (str, size, arg);
     }
 
   return USB_UNSUPPORT;
@@ -628,6 +611,7 @@ neug_setup_endpoints_for_interface (uint16_t interface, int stop)
        {
          usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
          usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
+         /* Start with no data receiving (ENDP3 not enabled) */
        }
       else
        {
@@ -677,8 +661,6 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
        }
       /* Do nothing when current_conf == value */
       return USB_SUCCESS;
-
-      return USB_SUCCESS;
     default:
       break;
     }
@@ -687,11 +669,11 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
 }
 
 
-int usb_cb_interface (uint8_t cmd, struct control_info *detail)
+int usb_cb_interface (uint8_t cmd, struct req_args *arg)
 {
   const uint8_t zero = 0;
-  uint16_t interface = detail->index;
-  uint16_t alt = detail->value;
+  uint16_t interface = arg->index;
+  uint16_t alt = arg->value;
 
   if (interface >= NUM_INTERFACES)
     return USB_UNSUPPORT;
@@ -708,8 +690,7 @@ int usb_cb_interface (uint8_t cmd, struct control_info *detail)
        }
 
     case USB_GET_INTERFACE:
-      usb_lld_reply_request (&zero, 1, detail);
-      return USB_SUCCESS;
+      return usb_lld_reply_request (&zero, 1, arg);
 
     default:
     case USB_QUERY_INTERFACE:
@@ -726,13 +707,13 @@ usb_intr (void *arg)
   chopstx_intr_t interrupt;
 
   (void)arg;
-  usb_lld_init (vcom_config_desc[7]);
+  usb_lld_init (VCOM_FEATURE_BUS_POWERED);
   chopstx_claim_irq (&interrupt, INTR_REQ_USB);
-  usb_interrupt_handler ();
+  usb_interrupt_handler ();    /* For old SYS < 3.0 */
 
   while (1)
     {
-      chopstx_intr_wait (&interrupt);
+      chopstx_poll (NULL, 1, &interrupt);
 
       /* Process interrupt. */
       usb_interrupt_handler ();
@@ -764,24 +745,28 @@ static void fill_serial_no_by_unique_id (void)
       p[i*4+3] = 0;
     }
 }
-\f
-void
-EP1_IN_Callback (void)
-{
-  chopstx_mutex_lock (&usb_mtx);
-  chopstx_cond_signal (&cnd_usb);
-  chopstx_mutex_unlock (&usb_mtx);
-}
+
 
 void
-EP2_IN_Callback (void)
+usb_cb_tx_done (uint8_t ep_num)
 {
+  if (ep_num == ENDP1)
+    {
+      chopstx_mutex_lock (&usb_mtx);
+      chopstx_cond_signal (&usb_cnd);
+      chopstx_mutex_unlock (&usb_mtx);
+    }
+  else if (ep_num == ENDP2)
+    {
+      /* INTERRUPT Transfer done */
+    }
 }
 
 void
-EP3_OUT_Callback (void)
+usb_cb_rx_ready (uint8_t ep_num)
 {
-  usb_lld_rx_enable (ENDP3);
+  if (ep_num == ENDP3)
+    usb_lld_rx_enable (ENDP3);
 }
 \f
 typedef uint32_t eventmask_t;
@@ -901,6 +886,15 @@ calculate_regnual_entry_address (const uint8_t *addr)
 }
 
 
+static int
+check_usb_status (void *arg)
+{
+  (void)arg;
+
+  return (connected || bDeviceState != CONFIGURED
+         || fsij_device_state != FSIJ_DEVICE_RUNNING);
+}
+
 /*
  * Entry point.
  *
@@ -923,7 +917,7 @@ main (int argc, char **argv)
   event_flag_init (&led_event);
 
   chopstx_mutex_init (&usb_mtx);
-  chopstx_cond_init (&cnd_usb);
+  chopstx_cond_init (&usb_cnd);
 
 #ifdef FRAUCHEKY_SUPPORT
   if (fraucheky_enabled ())
@@ -954,7 +948,7 @@ main (int argc, char **argv)
 
  not_configured:
   count = 0;
-  /* A run-up */
+  /* Initial run-up */
   while (count < NEUG_PRE_LOOP || bDeviceState != CONFIGURED)
     {
       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
@@ -971,7 +965,7 @@ main (int argc, char **argv)
       chopstx_mutex_lock (&usb_mtx);
     }
 
-  /* Holding USB_MTX.  */
+  /* Holding USB_MTX...  */
   while (1)
     {
       int last_was_fullsizepacket = 0;
@@ -979,21 +973,29 @@ main (int argc, char **argv)
       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
        break;
 
+      chopstx_mutex_unlock (&usb_mtx);
       while (1)
        {
-         wait_usb_connection = 5000*1000;
-         if (connected || bDeviceState != CONFIGURED
-             || fsij_device_state != FSIJ_DEVICE_RUNNING)
+         chopstx_poll_cond_t poll_desc;
+         uint32_t usec = 5000*1000;
+
+         poll_desc.type = CHOPSTX_POLL_COND;
+         poll_desc.ready = 0;
+         poll_desc.cond = &usb_cnd;
+         poll_desc.mutex = &usb_mtx;
+         poll_desc.check = check_usb_status;
+         poll_desc.arg = NULL;
+
+         if (chopstx_poll (&usec, 1, &poll_desc))
            break;
 
-         chopstx_mutex_unlock (&usb_mtx);
+         /* Timeout */
          neug_flush ();
          neug_mode_select (line_coding.paritytype);
          event_flag_signal (&led_event, LED_TWOSHOTS);
-         chopstx_usec_wait_var (&wait_usb_connection);
-         chopstx_mutex_lock (&usb_mtx);
        }
 
+      chopstx_mutex_lock (&usb_mtx);
       if (bDeviceState != CONFIGURED)
        goto not_configured;
 
@@ -1043,7 +1045,7 @@ main (int argc, char **argv)
 
              /* Prepare sending random data.  */
              usb_lld_tx_enable (ENDP1, i * 4);
-             chopstx_cond_wait (&cnd_usb, &usb_mtx);
+             chopstx_cond_wait (&usb_cnd, &usb_mtx);
              count++;
            }
        }
index 9dde205..d3f3ee4 100644 (file)
@@ -582,8 +582,8 @@ rng (void *arg)
   chopstx_cond_init (&mode_cond);
 
   /* Enable ADCs */
-  adc_start ();
   chopstx_claim_irq (&adc_intr, INTR_REQ_DMA1_Channel1);
+  adc_start ();
 
   ep_init (mode);
   while (!rng_should_terminate)
@@ -641,7 +641,6 @@ rng (void *arg)
     }
 
   adc_stop ();
-  chopstx_release_irq (&adc_intr);
 
   return NULL;
 }
index 586a79f..9ec3b06 100644 (file)
--- a/src/sys.c
+++ b/src/sys.c
@@ -1,7 +1,7 @@
 /*
  * sys.c - system routines for the initial page for STM32F103.
  *
- * Copyright (C) 2013, 2014, 2015 Flying Stone Technology
+ * Copyright (C) 2013, 2014, 2015, 2016  Flying Stone Technology
  * Author: NIIBE Yutaka <gniibe@fsij.org>
  *
  * Copying and distribution of this file, with or without modification,
 #include <stdlib.h>
 #include "board.h"
 
-#include "clk_gpio_init.c"
-
-#define CORTEX_PRIORITY_BITS    4
-#define CORTEX_PRIORITY_MASK(n)  ((n) << (8 - CORTEX_PRIORITY_BITS))
-#define USB_LP_CAN1_RX0_IRQn    20
-#define STM32_USB_IRQ_PRIORITY   11
-
-struct NVIC {
-  uint32_t ISER[8];
-  uint32_t unused1[24];
-  uint32_t ICER[8];
-  uint32_t unused2[24];
-  uint32_t ISPR[8];
-  uint32_t unused3[24];
-  uint32_t ICPR[8];
-  uint32_t unused4[24];
-  uint32_t IABR[8];
-  uint32_t unused5[56];
-  uint32_t IPR[60];
-};
-
-static struct NVIC *const NVICBase = ((struct NVIC *const)0xE000E100);
-#define NVIC_ISER(n)   (NVICBase->ISER[n >> 5])
-#define NVIC_ICPR(n)   (NVICBase->ICPR[n >> 5])
-#define NVIC_IPR(n)    (NVICBase->IPR[n >> 2])
-
-static void
-nvic_enable_vector (uint32_t n, uint32_t prio)
-{
-  unsigned int sh = (n & 3) << 3;
+#include "clk_gpio_init-stm32.c"
 
-  NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (prio << sh);
-  NVIC_ICPR (n) = 1 << (n & 0x1F);
-  NVIC_ISER (n) = 1 << (n & 0x1F);
-}
 
 static void
 usb_cable_config (int enable)
@@ -118,13 +85,6 @@ usb_lld_sys_init (void)
 
   usb_cable_config (1);
   RCC->APB1ENR |= RCC_APB1ENR_USBEN;
-  nvic_enable_vector (USB_LP_CAN1_RX0_IRQn,
-                     CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
-  /*
-   * Note that we also have other IRQ(s):
-   *   USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
-   *   USBWakeUp_IRQn (suspend/resume)
-   */
   RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
   RCC->APB1RSTR = 0;
 }
@@ -423,8 +383,8 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
 const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
   3*2+2,            /* bLength */
   0x03,                     /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
-  /* sys version: "2.1" */
-  '2', 0, '.', 0, '1', 0,
+  /* sys version: "3.0" */
+  '3', 0, '.', 0, '0', 0,
 };
 
 const uint32_t __attribute__((section(".sys.board_id")))
index fd4bc08..3710f20 100644 (file)
@@ -1,9 +1,3 @@
-#define USB_DEVICE_DESCRIPTOR_TYPE              0x01
-#define USB_CONFIGURATION_DESCRIPTOR_TYPE       0x02
-#define USB_STRING_DESCRIPTOR_TYPE              0x03
-#define USB_INTERFACE_DESCRIPTOR_TYPE           0x04
-#define USB_ENDPOINT_DESCRIPTOR_TYPE            0x05
-
 #define STANDARD_ENDPOINT_DESC_SIZE             0x09
 
 /* endpoints enumeration */
@@ -24,7 +18,7 @@
 
 enum RECIPIENT_TYPE
 {
-  DEVICE_RECIPIENT,     /* Recipient device    */
+  DEVICE_RECIPIENT = 0, /* Recipient device    */
   INTERFACE_RECIPIENT,  /* Recipient interface */
   ENDPOINT_RECIPIENT,   /* Recipient endpoint  */
   OTHER_RECIPIENT
@@ -55,19 +49,22 @@ enum
   USB_SUCCESS = 1,
 };
 
-struct control_info {
+struct req_args {
   uint16_t value;
   uint16_t index;
   uint16_t len;
 };
 
 void usb_cb_device_reset (void);
-int usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail);
-int usb_cb_interface (uint8_t cmd, struct control_info *detail);
+int usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg);
+int usb_cb_interface (uint8_t cmd, struct req_args *arg);
 int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
-                          struct control_info *detail);
+                          struct req_args *arg);
 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, 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_rx_ready (uint8_t ep_num);
 
 enum {
   USB_EVENT_ADDRESS,
@@ -103,18 +100,17 @@ 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 control_info *ctrl);
+                          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 (void);
+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_feature (uint8_t feature);
-void usb_lld_set_data_to_recv (const void *p, size_t len);
+void usb_lld_set_data_to_recv (void *p, size_t len);
 
 void usb_lld_prepare_shutdown (void);
 void usb_lld_shutdown (void);
index ac96dda..80fbcc7 100644 (file)
@@ -62,6 +62,8 @@ struct DEVICE_INFO
   uint8_t bRequest;
   /**/
   uint16_t value;
+  uint16_t index;
+  uint16_t len;
 };
 
 static struct DEVICE_INFO device_info;
@@ -353,7 +355,7 @@ void usb_lld_init (uint8_t feature)
   dev_p->state = IN_DATA;
 
   usb_lld_set_configuration (0);
-  usb_lld_set_feature (feature);
+  dev_p->current_feature = feature;
 
   /* Reset USB */
   st103_set_cntr (CNTR_FRES);
@@ -462,26 +464,26 @@ static void handle_datastage_in (void)
   st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
 }
 
-typedef int (*HANDLER) (uint8_t req, struct control_info *detail);
+typedef int (*HANDLER) (uint8_t req, struct req_args *arg);
 
-static int std_none (uint8_t req, struct control_info *detail)
+static int std_none (uint8_t req, struct req_args *arg)
 {
-  (void)req; (void)detail;
+  (void)req; (void)arg;
   return USB_UNSUPPORT;
 }
 
-static int std_get_status (uint8_t req, struct control_info *detail)
+static int std_get_status (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
   uint16_t status_info = 0;
 
-  if (detail->value != 0 || detail->len != 2 || (detail->index >> 8) != 0
-      || (req & REQUEST_DIR) == 0)
+  if (arg->value != 0 || arg->len != 2 || (arg->index >> 8) != 0
+      || USB_SETUP_SET (req))
     return USB_UNSUPPORT;
 
   if (rcp == DEVICE_RECIPIENT)
     {
-      if (detail->index == 0)
+      if (arg->index == 0)
        {
          /* Get Device Status */
          uint8_t feature = dev_p->current_feature;
@@ -498,7 +500,7 @@ static int std_get_status (uint8_t req, struct control_info *detail)
          else /* Self-powered */
            status_info &= ~1;
 
-         return usb_lld_reply_request (&status_info, 2, detail);
+         return usb_lld_reply_request (&status_info, 2, arg);
        }
     }
   else if (rcp == INTERFACE_RECIPIENT)
@@ -508,21 +510,21 @@ static int std_get_status (uint8_t req, struct control_info *detail)
       if (dev_p->current_configuration == 0)
        return USB_UNSUPPORT;
 
-      r = usb_cb_interface (USB_QUERY_INTERFACE, detail);
+      r = usb_cb_interface (USB_QUERY_INTERFACE, arg);
       if (r != USB_SUCCESS)
        return USB_UNSUPPORT;
 
-      return usb_lld_reply_request (&status_info, 2, detail);
+      return usb_lld_reply_request (&status_info, 2, arg);
     }
   else if (rcp == ENDPOINT_RECIPIENT)
     {
-      uint8_t endpoint = (detail->index & 0x0f);
+      uint8_t endpoint = (arg->index & 0x0f);
       uint16_t status;
 
-      if ((detail->index & 0x70) || endpoint == ENDP0)
+      if ((arg->index & 0x70) || endpoint == ENDP0)
        return USB_UNSUPPORT;
 
-      if ((detail->index & 0x80))
+      if ((arg->index & 0x80))
        {
          status = st103_ep_get_tx_status (endpoint);
          if (status == 0)              /* Disabled */
@@ -539,25 +541,25 @@ static int std_get_status (uint8_t req, struct control_info *detail)
            status_info |= 1; /* OUT Endpoint stalled */
        }
 
-      return usb_lld_reply_request (&status_info, 2, detail);
+      return usb_lld_reply_request (&status_info, 2, arg);
     }
 
   return USB_UNSUPPORT;
 }
 
-static int std_clear_feature (uint8_t req, struct control_info *detail)
+static int std_clear_feature (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  if ((req & REQUEST_DIR) == 1)
+  if (USB_SETUP_GET (req))
     return USB_UNSUPPORT;
 
   if (rcp == DEVICE_RECIPIENT)
     {
-      if (detail->len != 0 || detail->index != 0)
+      if (arg->len != 0 || arg->index != 0)
        return USB_UNSUPPORT;
 
-      if (detail->value == DEVICE_REMOTE_WAKEUP)
+      if (arg->value == DEVICE_REMOTE_WAKEUP)
        {
          dev_p->current_feature &= ~(1 << 5);
          return USB_SUCCESS;
@@ -565,17 +567,17 @@ static int std_clear_feature (uint8_t req, struct control_info *detail)
     }
   else if (rcp == ENDPOINT_RECIPIENT)
     {
-      uint8_t endpoint = (detail->index & 0x0f);
+      uint8_t endpoint = (arg->index & 0x0f);
       uint16_t status;
 
       if (dev_p->current_configuration == 0)
        return USB_UNSUPPORT;
 
-      if (detail->len != 0 || (detail->index >> 8) != 0
-         || detail->value != ENDPOINT_STALL || endpoint == ENDP0)
+      if (arg->len != 0 || (arg->index >> 8) != 0
+         || arg->value != ENDPOINT_STALL || endpoint == ENDP0)
        return USB_UNSUPPORT;
 
-      if ((detail->index & 0x80))
+      if ((arg->index & 0x80))
        status = st103_ep_get_tx_status (endpoint);
       else
        status = st103_ep_get_rx_status (endpoint);
@@ -583,7 +585,7 @@ static int std_clear_feature (uint8_t req, struct control_info *detail)
       if (status == 0)         /* Disabled */
        return USB_UNSUPPORT;
 
-      if (detail->index & 0x80)                /* IN endpoint */
+      if (arg->index & 0x80)           /* IN endpoint */
        st103_ep_clear_dtog_tx (endpoint);
       else                     /* OUT endpoint */
        st103_ep_clear_dtog_rx (endpoint);
@@ -595,19 +597,19 @@ static int std_clear_feature (uint8_t req, struct control_info *detail)
   return USB_UNSUPPORT;
 }
 
-static int std_set_feature (uint8_t req, struct control_info *detail)
+static int std_set_feature (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  if ((req & REQUEST_DIR) == 1)
+  if (USB_SETUP_GET (req))
     return USB_UNSUPPORT;
 
   if (rcp == DEVICE_RECIPIENT)
     {
-      if (detail->len != 0 || detail->index != 0)
+      if (arg->len != 0 || arg->index != 0)
        return USB_UNSUPPORT;
 
-      if (detail->value == DEVICE_REMOTE_WAKEUP)
+      if (arg->value == DEVICE_REMOTE_WAKEUP)
        {
          dev_p->current_feature |= 1 << 5;
          // event??
@@ -616,17 +618,17 @@ static int std_set_feature (uint8_t req, struct control_info *detail)
     }
   else if (rcp == ENDPOINT_RECIPIENT)
     {
-      uint8_t endpoint = (detail->index & 0x0f);
+      uint8_t endpoint = (arg->index & 0x0f);
       uint32_t status;
 
       if (dev_p->current_configuration == 0)
        return USB_UNSUPPORT;
 
-      if (detail->len != 0 || (detail->index >> 8) != 0
-         || detail->value != 0 || endpoint == ENDP0)
+      if (arg->len != 0 || (arg->index >> 8) != 0
+         || arg->value != 0 || endpoint == ENDP0)
        return USB_UNSUPPORT;
 
-      if ((detail->index & 0x80))
+      if ((arg->index & 0x80))
        status = st103_ep_get_tx_status (endpoint);
       else
        status = st103_ep_get_rx_status (endpoint);
@@ -634,7 +636,7 @@ static int std_set_feature (uint8_t req, struct control_info *detail)
       if (status == 0)         /* Disabled */
        return USB_UNSUPPORT;
 
-      if (detail->index & 0x80)
+      if (arg->index & 0x80)
        /* IN endpoint */
        st103_ep_set_tx_status (endpoint, EP_TX_STALL);
       else
@@ -648,96 +650,94 @@ static int std_set_feature (uint8_t req, struct control_info *detail)
   return USB_UNSUPPORT;
 }
 
-static int std_set_address (uint8_t req, struct control_info *detail)
+static int std_set_address (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  if ((req & REQUEST_DIR) == 1)
+  if (USB_SETUP_GET (req))
     return USB_UNSUPPORT;
 
-  if (rcp == DEVICE_RECIPIENT && detail->len == 0 && detail->value <= 127
-      && detail->index == 0 && dev_p->current_configuration == 0)
+  if (rcp == DEVICE_RECIPIENT && arg->len == 0 && arg->value <= 127
+      && arg->index == 0 && dev_p->current_configuration == 0)
     return USB_SUCCESS;
 
   return USB_UNSUPPORT;
 }
 
-static int std_get_descriptor (uint8_t req, struct control_info *detail)
+static int std_get_descriptor (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  if ((req & REQUEST_DIR) == 0)
+  if (USB_SETUP_SET (req))
     return USB_UNSUPPORT;
 
-  return usb_cb_get_descriptor (rcp, (detail->value >> 8),
-                               (detail->value & 0xff), detail);
+  return usb_cb_get_descriptor (rcp, (arg->value >> 8),
+                               (arg->value & 0xff), arg);
 }
 
-static int std_get_configuration (uint8_t req,  struct control_info *detail)
+static int std_get_configuration (uint8_t req,  struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  (void)detail;
-  if ((req & REQUEST_DIR) == 0)
+  if (USB_SETUP_SET (req))
     return USB_UNSUPPORT;
 
   if (rcp == DEVICE_RECIPIENT)
-    return usb_lld_reply_request (&dev_p->current_configuration, 1, detail);
+    return usb_lld_reply_request (&dev_p->current_configuration, 1, arg);
 
   return USB_UNSUPPORT;
 }
 
-static int std_set_configuration (uint8_t req, struct control_info *detail)
+static int std_set_configuration (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  if ((req & REQUEST_DIR) == 1)
+  if (USB_SETUP_GET (req))
     return USB_UNSUPPORT;
 
-  if (rcp == DEVICE_RECIPIENT && detail->index == 0 && detail->len == 0)
-    return usb_cb_handle_event (USB_EVENT_CONFIG, detail->value);
+  if (rcp == DEVICE_RECIPIENT && arg->index == 0 && arg->len == 0)
+    return usb_cb_handle_event (USB_EVENT_CONFIG, arg->value);
 
   return USB_UNSUPPORT;
 }
 
-static int std_get_interface (uint8_t req, struct control_info *detail)
+static int std_get_interface (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  if ((req & REQUEST_DIR) == 0)
+  if (USB_SETUP_SET (req))
     return USB_UNSUPPORT;
 
   if (rcp == INTERFACE_RECIPIENT)
     {
-      if (detail->value != 0 || (detail->index >> 8) != 0 || detail->len != 1)
+      if (arg->value != 0 || (arg->index >> 8) != 0 || arg->len != 1)
        return USB_UNSUPPORT;
 
       if (dev_p->current_configuration == 0)
        return USB_UNSUPPORT;
 
-      return usb_cb_interface (USB_GET_INTERFACE, detail);
+      return usb_cb_interface (USB_GET_INTERFACE, arg);
     }
 
   return USB_UNSUPPORT;
 }
 
-static int std_set_interface (uint8_t req, struct control_info *detail)
+static int std_set_interface (uint8_t req, struct req_args *arg)
 {
   uint8_t rcp = req & RECIPIENT;
 
-  if ((req & REQUEST_DIR) == 1 || rcp != INTERFACE_RECIPIENT
-      || detail->len != 0 || (detail->index >> 8) != 0
-      || (detail->value >> 8) != 0 || dev_p->current_configuration == 0)
+  if (USB_SETUP_GET (req) || rcp != INTERFACE_RECIPIENT
+      || arg->len != 0 || (arg->index >> 8) != 0
+      || (arg->value >> 8) != 0 || dev_p->current_configuration == 0)
     return USB_UNSUPPORT;
 
-  return usb_cb_interface (USB_SET_INTERFACE, detail);
+  return usb_cb_interface (USB_SET_INTERFACE, arg);
 }
 
 
 static void handle_setup0 (void)
 {
   const uint16_t *pw;
-  struct control_info ctrl;
   uint16_t w;
   uint8_t req_no;
   int r = USB_UNSUPPORT;
@@ -749,11 +749,11 @@ static void handle_setup0 (void)
   dev_p->bmRequestType = w & 0xff;
   dev_p->bRequest = req_no = w >> 8;
   pw++;
-  ctrl.value = *pw++;
+  dev_p->value = *pw++;
   pw++;
-  ctrl.index  = *pw++;
+  dev_p->index = *pw++;
   pw++;
-  ctrl.len = *pw;
+  dev_p->len = *pw;
 
   data_p->addr = NULL;
   data_p->len = 0;
@@ -777,11 +777,13 @@ static void handle_setup0 (void)
            default: handler = std_none;  break;
            }
 
-         r = (*handler) (dev_p->bmRequestType, &ctrl);
+         r = (*handler) (dev_p->bmRequestType,
+                         (struct req_args *)&dev_p->value);
        }
     }
   else
-    r = usb_cb_setup (dev_p->bmRequestType, req_no, &ctrl);
+    r = usb_cb_setup (dev_p->bmRequestType, req_no,
+                     (struct req_args *)&dev_p->value);
 
   if (r != USB_SUCCESS)
     dev_p->state = STALLED;
@@ -789,8 +791,7 @@ static void handle_setup0 (void)
     {
       if (USB_SETUP_SET (dev_p->bmRequestType))
        {
-         dev_p->value = ctrl.value;
-         if (ctrl.len == 0)
+         if (dev_p->len == 0)
            {
              dev_p->state = WAIT_STATUS_IN;
              st103_set_tx_count (ENDP0, 0);
@@ -819,8 +820,8 @@ static void handle_in0 (void)
          usb_cb_handle_event (USB_EVENT_ADDRESS, dev_p->value);
        }
       else
-       usb_cb_ctrl_write_finish  (dev_p->bmRequestType, dev_p->bRequest,
-                                  dev_p->value);
+       usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest,
+                                 (struct req_args *)&dev_p->value);
 
       dev_p->state = STALLED;
     }
@@ -842,27 +843,6 @@ static void handle_out0 (void)
     dev_p->state = STALLED;
 }
 \f
-static void nop_proc (void)
-{
-}
-
-#define WEAK __attribute__ ((weak, alias ("nop_proc")))
-void WEAK EP1_IN_Callback (void);
-void WEAK EP2_IN_Callback (void);
-void WEAK EP3_IN_Callback (void);
-void WEAK EP4_IN_Callback (void);
-void WEAK EP5_IN_Callback (void);
-void WEAK EP6_IN_Callback (void);
-void WEAK EP7_IN_Callback (void);
-
-void WEAK EP1_OUT_Callback (void);
-void WEAK EP2_OUT_Callback (void);
-void WEAK EP3_OUT_Callback (void);
-void WEAK EP4_OUT_Callback (void);
-void WEAK EP5_OUT_Callback (void);
-void WEAK EP6_OUT_Callback (void);
-void WEAK EP7_OUT_Callback (void);
-
 static void
 usb_handle_transfer (uint16_t istr_value)
 {
@@ -900,37 +880,21 @@ usb_handle_transfer (uint16_t istr_value)
       if ((ep_value & EP_CTR_RX))
        {
          st103_ep_clear_ctr_rx (ep_index);
-         switch ((ep_index - 1))
-           {
-           case 0: EP1_OUT_Callback ();  break;
-           case 1: EP2_OUT_Callback ();  break;
-           case 2: EP3_OUT_Callback ();  break;
-           case 3: EP4_OUT_Callback ();  break;
-           case 4: EP5_OUT_Callback ();  break;
-           case 5: EP6_OUT_Callback ();  break;
-           case 6: EP7_OUT_Callback ();  break;
-           }
+         usb_cb_rx_ready (ep_index);
        }
 
       if ((ep_value & EP_CTR_TX))
        {
          st103_ep_clear_ctr_tx (ep_index);
-         switch ((ep_index - 1))
-           {
-           case 0: EP1_IN_Callback ();  break;
-           case 1: EP2_IN_Callback ();  break;
-           case 2: EP3_IN_Callback ();  break;
-           case 3: EP4_IN_Callback ();  break;
-           case 4: EP5_IN_Callback ();  break;
-           case 5: EP6_IN_Callback ();  break;
-           case 6: EP7_IN_Callback ();  break;
-           }
+         usb_cb_tx_done (ep_index);
        }
     }
 }
 \f
-void usb_lld_reset (void)
+void usb_lld_reset (uint8_t feature)
 {
+  usb_lld_set_configuration (0);
+  dev_p->current_feature = feature;
   st103_set_btable ();
   st103_set_daddr (0);
 }
@@ -1037,14 +1001,9 @@ uint8_t usb_lld_current_configuration (void)
   return dev_p->current_configuration;
 }
 
-void usb_lld_set_feature (uint8_t feature)
-{
-  dev_p->current_feature = feature;
-}
-
-void usb_lld_set_data_to_recv (const void *p, size_t len)
+void usb_lld_set_data_to_recv (void *p, size_t len)
 {
-  data_p->addr = (uint8_t *)p;
+  data_p->addr = p;
   data_p->len = len;
 }
 
@@ -1129,7 +1088,7 @@ void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n)
  * BUFLEN: size of the data.
  */
 int
-usb_lld_reply_request (const void *buf, size_t buflen, struct control_info *ctl)
+usb_lld_reply_request (const void *buf, size_t buflen, struct req_args *ctl)
 {
   uint32_t len_asked = ctl->len;
   uint32_t len;