summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremiah McCarthy <[email protected]>2021-04-05 17:52:33 -0400
committerJeremiah McCarthy <[email protected]>2021-04-05 17:52:33 -0400
commitc39b7b8177acbab23e82fee295d5f3205aa9752c (patch)
tree4b821dba031b4ab6b3ee8af618a96ce506e1b71e
parentbc2cb99780a0bc0359195a4be8e556f71da5a70b (diff)
Add DFU runtime and mode "class"
With the runtime and mode portions in separate classes, a single application should only be building with one or the other enabled. In some applications both might be desired at build time. The CFG_TUD_DFU_RUNTIME_AND_MODE option creates a DFU class, which asks the application which mode to initialize to. This allows a runtime change between RT and DFU mode, by just reinitializing tusb.
-rw-r--r--src/class/dfu/dfu_mode_device.c4
-rw-r--r--src/class/dfu/dfu_rt_and_mode_device.c114
-rw-r--r--src/class/dfu/dfu_rt_and_mode_device.h57
-rw-r--r--src/class/dfu/dfu_rt_device.c2
-rw-r--r--src/device/usbd.c12
-rw-r--r--src/tusb.h6
-rw-r--r--src/tusb_option.h10
7 files changed, 202 insertions, 3 deletions
diff --git a/src/class/dfu/dfu_mode_device.c b/src/class/dfu/dfu_mode_device.c
index 59cea7673..0b80b103d 100644
--- a/src/class/dfu/dfu_mode_device.c
+++ b/src/class/dfu/dfu_mode_device.c
@@ -26,7 +26,7 @@
#include "tusb_option.h"
-#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_MODE)
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_MODE) || (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RUNTIME_AND_MODE)
#include "dfu_mode_device.h"
#include "device/usbd_pvt.h"
@@ -590,4 +590,4 @@ static bool dfu_mode_state_machine(uint8_t rhport, tusb_control_request_t const
}
- #endif
+#endif
diff --git a/src/class/dfu/dfu_rt_and_mode_device.c b/src/class/dfu/dfu_rt_and_mode_device.c
new file mode 100644
index 000000000..d555a1d58
--- /dev/null
+++ b/src/class/dfu/dfu_rt_and_mode_device.c
@@ -0,0 +1,114 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 XMOS LIMITED
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb_option.h"
+
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RUNTIME_AND_MODE)
+
+#include "dfu_rt_and_mode_device.h"
+
+#include "dfu_mode_device.h"
+#include "dfu_rt_device.h"
+#include "device/usbd_pvt.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+typedef struct
+{
+ void (* init ) (void);
+ void (* reset ) (uint8_t rhport);
+ uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len);
+ bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
+} dfu_local_driver_t;
+
+static dfu_local_driver_t ctx =
+{
+ .init = NULL,
+ .reset = NULL,
+ .open = NULL,
+ .control_xfer_cb = NULL
+};
+
+static dfu_protocol_type_t mode = 0x00;
+
+//--------------------------------------------------------------------+
+// USBD Driver API
+//--------------------------------------------------------------------+
+void dfu_init(void)
+{
+ mode = dfu_init_in_mode_cb();
+
+ switch (mode)
+ {
+ case DFU_PROTOCOL_RT:
+ {
+ ctx.init = dfu_rtd_init;
+ ctx.reset = dfu_rtd_reset;
+ ctx.open = dfu_rtd_open;
+ ctx.control_xfer_cb = dfu_rtd_control_xfer_cb;
+ }
+ break;
+
+ case DFU_PROTOCOL_DFU:
+ {
+ ctx.init = dfu_mode_init;
+ ctx.reset = dfu_mode_reset;
+ ctx.open = dfu_mode_open;
+ ctx.control_xfer_cb = dfu_mode_control_xfer_cb;
+ }
+ break;
+
+ default:
+ {
+ TU_LOG2(" DFU Unexpected mode: %u\r\n", mode);
+ }
+ break;
+ }
+
+ ctx.init();
+}
+
+void dfu_reset(uint8_t rhport)
+{
+ ctx.reset(rhport);
+}
+
+uint16_t dfu_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len)
+{
+ return ctx.open(rhport, itf_desc, max_len);
+}
+
+bool dfu_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request)
+{
+ return ctx.control_xfer_cb(rhport, stage, request);
+}
+
+#endif
diff --git a/src/class/dfu/dfu_rt_and_mode_device.h b/src/class/dfu/dfu_rt_and_mode_device.h
new file mode 100644
index 000000000..9734a031c
--- /dev/null
+++ b/src/class/dfu/dfu_rt_and_mode_device.h
@@ -0,0 +1,57 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 XMOS LIMITED
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef _TUSB_DFU_RT_AND_MODE_DEVICE_H_
+#define _TUSB_DFU_RT_AND_MODE_DEVICE_H_
+
+#include "common/tusb_common.h"
+#include "device/usbd.h"
+#include "dfu.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// Application Callback API (weak is optional)
+//--------------------------------------------------------------------+
+// Invoked when the driver needs to determine the callbacks to use
+dfu_protocol_type_t dfu_init_in_mode_cb();
+
+//--------------------------------------------------------------------+
+// Internal Class Driver API
+//--------------------------------------------------------------------+
+void dfu_init(void);
+void dfu_reset(uint8_t rhport);
+uint16_t dfu_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
+bool dfu_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_DFU_RT_AND_MODE_DEVICE_H_ */
diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c
index 806bfba2e..d1d028d69 100644
--- a/src/class/dfu/dfu_rt_device.c
+++ b/src/class/dfu/dfu_rt_device.c
@@ -26,7 +26,7 @@
#include "tusb_option.h"
-#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RUNTIME)
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RUNTIME) || (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RUNTIME_AND_MODE)
#include "dfu_rt_device.h"
#include "device/usbd_pvt.h"
diff --git a/src/device/usbd.c b/src/device/usbd.c
index de0e7b0b7..6f2262feb 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -199,6 +199,18 @@ static usbd_class_driver_t const _usbd_driver[] =
},
#endif
+ #if CFG_TUD_DFU_RUNTIME_AND_MODE
+ {
+ DRIVER_NAME("DFU-RT-MODE")
+ .init = dfu_init,
+ .reset = dfu_reset,
+ .open = dfu_open,
+ .control_xfer_cb = dfu_control_xfer_cb,
+ .xfer_cb = NULL,
+ .sof = NULL
+ },
+ #endif
+
#if CFG_TUD_NET
{
DRIVER_NAME("NET")
diff --git a/src/tusb.h b/src/tusb.h
index c9558515c..6eab4bee2 100644
--- a/src/tusb.h
+++ b/src/tusb.h
@@ -100,6 +100,12 @@
#include "class/dfu/dfu_mode_device.h"
#endif
+ #if CFG_TUD_DFU_RUNTIME_AND_MODE
+ #include "class/dfu/dfu_rt_and_mode_device.h"
+ #include "class/dfu/dfu_rt_device.h"
+ #include "class/dfu/dfu_mode_device.h"
+ #endif
+
#if CFG_TUD_NET
#include "class/net/net_device.h"
#endif
diff --git a/src/tusb_option.h b/src/tusb_option.h
index 3cd3df9f2..4c2204964 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -241,6 +241,10 @@
#define CFG_TUD_DFU_MODE 0
#endif
+#ifndef CFG_TUD_DFU_RUNTIME_AND_MODE
+ #define CFG_TUD_DFU_RUNTIME_AND_MODE 0
+#endif
+
#ifndef CFG_TUD_DFU_TRANSFER_BUFFER_SIZE
#define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 64
#endif
@@ -285,6 +289,12 @@
#error Control Endpoint Max Packet Size cannot be larger than 64
#endif
+#if (CFG_TUD_DFU_RUNTIME_AND_MODE && CFG_TUD_DFU_RUNTIME) \
+ || (CFG_TUD_DFU_RUNTIME_AND_MODE && CFG_TUD_DFU_MODE) \
+ || (CFG_TUD_DFU_RUNTIME && CFG_TUD_DFU_MODE)
+ #error Only one of CFG_TUD_DFU_RUNTIME_AND_MODE, CFG_TUD_DFU_RUNTIME, and CFG_TUD_DFU_MODE can be enabled in a single build
+#endif
+
#endif /* _TUSB_OPTION_H_ */
/** @} */