summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorhathach <[email protected]>2022-03-07 23:03:37 +0700
committerhathach <[email protected]>2022-03-07 23:03:51 +0700
commit707a633de3b4f47cf00396e16adb7946fa127880 (patch)
tree4f92b00c28037ea3f6e5b1f2a5a99b146f3ee9d4 /src/device
parentce60e98f6da2030f8fe8c8b6c63a7a33019e6c74 (diff)
added dcd_sof_enable(), tud_sof_isr_set()
make number of interface configurable (default to 8) CFG_TUD_INTERFACE_MAX
Diffstat (limited to 'src/device')
-rw-r--r--src/device/dcd.h15
-rw-r--r--src/device/usbd.c18
-rw-r--r--src/device/usbd.h6
3 files changed, 37 insertions, 2 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h
index 8efbc90ef..3eac6711f 100644
--- a/src/device/dcd.h
+++ b/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
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 7926689b7..8662d5b84 100644
--- a/src/device/usbd.c
+++ b/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);
}
diff --git a/src/device/usbd.h b/src/device/usbd.h
index b2bf8ba9d..72401a7e9 100644
--- a/src/device/usbd.h
+++ b/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