diff options
author | Marti Bolivar <mbolivar@leaflabs.com> | 2012-07-31 13:03:12 -0400 |
---|---|---|
committer | Marti Bolivar <mbolivar@leaflabs.com> | 2012-07-31 15:04:49 -0400 |
commit | 9e49090ac6fb41645e5d09145cc4163e65565788 (patch) | |
tree | f5247e9864c1476f68110e9deae47ae3f36e2651 | |
parent | f4c716a527f374c96923e2f81f6a605335e56aba (diff) | |
download | librambutan-9e49090ac6fb41645e5d09145cc4163e65565788.tar.gz librambutan-9e49090ac6fb41645e5d09145cc4163e65565788.zip |
usb_cdcacm: Add hook system.
Provide hooks so users can reach into the CDC ACM callbacks with their
own code. We'll use this to move the bootloader reset signals to
Wirish.
Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
-rw-r--r-- | libmaple/include/libmaple/usb_cdcacm.h | 13 | ||||
-rw-r--r-- | libmaple/usb/stm32f1/usb_cdcacm.c | 31 |
2 files changed, 44 insertions, 0 deletions
diff --git a/libmaple/include/libmaple/usb_cdcacm.h b/libmaple/include/libmaple/usb_cdcacm.h index 85b4f5e..3b15d48 100644 --- a/libmaple/include/libmaple/usb_cdcacm.h +++ b/libmaple/include/libmaple/usb_cdcacm.h @@ -94,6 +94,19 @@ uint16 usb_cdcacm_get_pending(void); uint8 usb_cdcacm_get_dtr(void); uint8 usb_cdcacm_get_rts(void); +/* + * Hack: hooks for bootloader reset signalling + */ + +#define USB_CDCACM_HOOK_RX 0x1 +#define USB_CDCACM_HOOK_IFACE_SETUP 0x2 + +void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)); + +static __always_inline void usb_cdcacm_remove_hooks(unsigned hook_flags) { + usb_cdcacm_set_hooks(hook_flags, 0); +} + #ifdef __cplusplus } #endif diff --git a/libmaple/usb/stm32f1/usb_cdcacm.c b/libmaple/usb/stm32f1/usb_cdcacm.c index 75bbc4f..ee3c8e3 100644 --- a/libmaple/usb/stm32f1/usb_cdcacm.c +++ b/libmaple/usb/stm32f1/usb_cdcacm.c @@ -354,6 +354,22 @@ USER_STANDARD_REQUESTS User_Standard_Requests = { }; /* + * User hooks + */ + +static void (*rx_hook)(unsigned, void*) = 0; +static void (*iface_setup_hook)(unsigned, void*) = 0; + +void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)) { + if (hook_flags & USB_CDCACM_HOOK_RX) { + rx_hook = hook; + } + if (hook_flags & USB_CDCACM_HOOK_IFACE_SETUP) { + iface_setup_hook = hook; + } +} + +/* * CDC ACM interface */ @@ -522,6 +538,10 @@ static void vcomDataRxCb(void) { } usb_copy_from_pma(vcomBufferRx, newBytes, USB_CDCACM_RX_ADDR); + + if (rx_hook) { + rx_hook(USB_CDCACM_HOOK_RX, 0); + } } static uint8* vcomGetSetLineCoding(uint16 length) { @@ -607,6 +627,12 @@ static RESULT usbDataSetup(uint8 request) { CopyRoutine = NULL; if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + /* Call the user hook first. */ + if (iface_setup_hook) { + uint8 req_copy = request; + iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy); + } + switch (request) { case (USB_CDCACM_GET_LINE_CODING): CopyRoutine = vcomGetSetLineCoding; @@ -636,6 +662,11 @@ static RESULT usbNoDataSetup(uint8 request) { /* we support set com feature but dont handle it */ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + /* Call the user hook first. */ + if (iface_setup_hook) { + uint8 req_copy = request; + iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy); + } switch (request) { case (USB_CDCACM_SET_COMM_FEATURE): |