aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-07-31 13:03:12 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-07-31 15:04:49 -0400
commit9e49090ac6fb41645e5d09145cc4163e65565788 (patch)
treef5247e9864c1476f68110e9deae47ae3f36e2651 /libmaple
parentf4c716a527f374c96923e2f81f6a605335e56aba (diff)
downloadlibrambutan-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>
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/include/libmaple/usb_cdcacm.h13
-rw-r--r--libmaple/usb/stm32f1/usb_cdcacm.c31
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):