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_ */ /** @} */