USB DFU run-time support

This commit is contained in:
Hubert Denkmair 2016-04-22 11:47:25 +02:00
parent a58dcb2a2f
commit 3f06d8b5cf
5 changed files with 96 additions and 0 deletions

29
include/dfu.h Normal file
View File

@ -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();

View File

@ -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);

54
src/dfu.c Normal file
View File

@ -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 <stdint.h>
#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();
}

View File

@ -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();
}
}
}

View File

@ -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;
}