From 3f06d8b5cfb1aeac287af771448ddaa7e166a901 Mon Sep 17 00:00:00 2001 From: Hubert Denkmair Date: Fri, 22 Apr 2016 11:47:25 +0200 Subject: [PATCH] USB DFU run-time support --- include/dfu.h | 29 +++++++++++++++++++++++ include/usbd_gs_can.h | 2 ++ src/dfu.c | 54 +++++++++++++++++++++++++++++++++++++++++++ src/main.c | 5 ++++ src/usbd_gs_can.c | 6 +++++ 5 files changed, 96 insertions(+) create mode 100644 include/dfu.h create mode 100644 src/dfu.c diff --git a/include/dfu.h b/include/dfu.h new file mode 100644 index 0000000..a018266 --- /dev/null +++ b/include/dfu.h @@ -0,0 +1,29 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2016 Hubert Denkmair + +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. + +*/ + +#pragma once + +void dfu_run_bootloader(); diff --git a/include/usbd_gs_can.h b/include/usbd_gs_can.h index efdad62..78bd66c 100644 --- a/include/usbd_gs_can.h +++ b/include/usbd_gs_can.h @@ -41,3 +41,5 @@ uint8_t USBD_GS_CAN_Transmit(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t le uint8_t USBD_GS_CAN_PrepareReceive(USBD_HandleTypeDef *pdev); bool USBD_GS_CAN_CustomDeviceRequest(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); bool USBD_GS_CAN_CustomInterfaceRequest(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +bool USBD_GS_CAN_DfuDetachRequested(USBD_HandleTypeDef *pdev); diff --git a/src/dfu.c b/src/dfu.c new file mode 100644 index 0000000..5e18f91 --- /dev/null +++ b/src/dfu.c @@ -0,0 +1,54 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2016 Hubert Denkmair + +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. + +*/ + +#include "dfu.h" +#include +#include "stm32f0xx_hal.h" + +#define SYSMEM_RESET_VECTOR 0x1fffC804 +#define RESET_TO_BOOTLOADER_MAGIC_CODE 0xDEADBEEF +#define BOOTLOADER_STACK_POINTER 0x20002250 + +uint32_t dfu_reset_to_bootloader_magic; + +void __initialize_hardware_early(void) +{ + if (dfu_reset_to_bootloader_magic == RESET_TO_BOOTLOADER_MAGIC_CODE) { + void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *) SYSMEM_RESET_VECTOR)); // system memory reset vector + dfu_reset_to_bootloader_magic = 0; + __set_MSP(BOOTLOADER_STACK_POINTER); + bootloader(); + while (42); + } else { + SystemInit(); + } +} + +void dfu_run_bootloader() +{ + dfu_reset_to_bootloader_magic = RESET_TO_BOOTLOADER_MAGIC_CODE; + NVIC_SystemReset(); +} diff --git a/src/main.c b/src/main.c index 7087a53..63e067a 100644 --- a/src/main.c +++ b/src/main.c @@ -37,6 +37,7 @@ THE SOFTWARE. #include "gs_usb.h" #include "can.h" #include "led.h" +#include "dfu.h" void HAL_MspInit(void); void SystemClock_Config(void); @@ -144,6 +145,10 @@ int main(void) led_update(&hLED); + if (USBD_GS_CAN_DfuDetachRequested(&hUSB)) { + dfu_run_bootloader(); + } + } } diff --git a/src/usbd_gs_can.c b/src/usbd_gs_can.c index c2ec2ce..eb234ef 100644 --- a/src/usbd_gs_can.c +++ b/src/usbd_gs_can.c @@ -595,3 +595,9 @@ uint8_t *USBD_GS_CAN_GetStrDesc(USBD_HandleTypeDef *pdev, uint8_t index, uint16_ return 0; } } + +bool USBD_GS_CAN_DfuDetachRequested(USBD_HandleTypeDef *pdev) +{ + USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData; + return hcan->dfu_detach_requested; +}