Pārlūkot izejas kodu

added dcd_sof_enable(), tud_sof_isr_set()

make number of interface configurable (default to 8)
CFG_TUD_INTERFACE_MAX
hathach 4 gadi atpakaļ
vecāks
revīzija
707a633de3
4 mainītis faili ar 41 papildinājumiem un 2 dzēšanām
  1. 15 0
      src/device/dcd.h
  2. 16 2
      src/device/usbd.c
  3. 6 0
      src/device/usbd.h
  4. 4 0
      src/tusb_option.h

+ 15 - 0
src/device/dcd.h

@@ -77,6 +77,11 @@ typedef struct TU_ATTR_ALIGNED(4)
       tusb_speed_t speed;
     } bus_reset;
 
+    // SOF
+    struct {
+      uint32_t frame_count;
+    }sof;
+
     // SETUP_RECEIVED
     tusb_control_request_t setup_received;
 
@@ -132,6 +137,9 @@ void dcd_connect(uint8_t rhport) TU_ATTR_WEAK;
 // Disconnect by disabling internal pull-up resistor on D+/D-
 void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
 
+// Enable/Disable Start-of-frame interrupt. Default is disabled
+void dcd_sof_enable(uint8_t rhport, bool en);
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+
@@ -185,6 +193,13 @@ extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool
 // helper to send transfer complete event
 extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr);
 
+static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr)
+{
+  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF };
+  event.sof.frame_count = frame_count;
+  dcd_event_handler(&event, in_isr);
+}
+
 #ifdef __cplusplus
  }
 #endif

+ 16 - 2
src/device/usbd.c

@@ -67,7 +67,7 @@ typedef struct
   volatile uint8_t cfg_num; // current active configuration (0x00 is not configured)
   uint8_t speed;
 
-  uint8_t itf2drv[16];     // map interface number to driver (0xff is invalid)
+  uint8_t itf2drv[CFG_TUD_INTERFACE_MAX];   // map interface number to driver (0xff is invalid)
   uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid )
 
   struct TU_ATTR_PACKED
@@ -269,6 +269,8 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid)
 // DCD Event
 //--------------------------------------------------------------------+
 
+static tud_sof_isr_t _sof_isr = NULL;
+
 enum { RHPORT_INVALID = 0xFFu };
 static uint8_t _usbd_rhport = RHPORT_INVALID;
 
@@ -393,6 +395,12 @@ bool tud_connect(void)
   return true;
 }
 
+void tud_sof_isr_set(tud_sof_isr_t sof_isr)
+{
+  _sof_isr = sof_isr;
+  dcd_sof_enable(_usbd_rhport, _sof_isr != NULL);
+}
+
 //--------------------------------------------------------------------+
 // USBD Task
 //--------------------------------------------------------------------+
@@ -435,11 +443,13 @@ bool tud_init (uint8_t rhport)
     driver->init();
   }
 
+  _usbd_rhport = rhport;
+  _sof_isr = NULL;
+
   // Init device controller driver
   dcd_init(rhport);
   dcd_int_enable(rhport);
 
-  _usbd_rhport = rhport;
 
   return true;
 }
@@ -1121,11 +1131,15 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
     break;
 
     case DCD_EVENT_SOF:
+      // SOF Handler
+      if (_sof_isr) _sof_isr(event->sof.frame_count);
+
       // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup
       // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational
       if ( _usbd_dev.suspended )
       {
         _usbd_dev.suspended = 0;
+
         dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME };
         osal_queue_send(_usbd_q, &event_resume, in_isr);
       }

+ 6 - 0
src/device/usbd.h

@@ -33,6 +33,8 @@
 extern "C" {
 #endif
 
+typedef void (*tud_sof_isr_t) (uint32_t frame_count);
+
 //--------------------------------------------------------------------+
 // Application API
 //--------------------------------------------------------------------+
@@ -84,6 +86,10 @@ bool tud_disconnect(void);
 // Return false on unsupported MCUs
 bool tud_connect(void);
 
+// Set Start-of-frame (1ms interval) IRQ handler
+// NULL means disabled, frame_count may not be supported on mcus
+void tud_sof_isr_set(tud_sof_isr_t sof_isr);
+
 // Carry out Data and Status stage of control transfer
 // - If len = 0, it is equivalent to sending status only
 // - If len > wLength : it will be truncated

+ 4 - 0
src/tusb_option.h

@@ -287,6 +287,10 @@
   #define CFG_TUD_ENDPOINT0_SIZE  64
 #endif
 
+#ifndef CFG_TUD_INTERFACE_MAX
+  #define CFG_TUD_INTERFACE_MAX   8
+#endif
+
 #ifndef CFG_TUD_CDC
   #define CFG_TUD_CDC             0
 #endif