add double tap support for ch32v2 using backup register 10

This commit is contained in:
hathach 2024-06-04 15:58:25 +07:00
parent bb2d563746
commit fcbb67e922
No known key found for this signature in database
GPG key ID: 26FAB84F615C3C52
4 changed files with 79 additions and 35 deletions

View file

@ -55,6 +55,10 @@ uint32_t SysTick_Config(uint32_t ticks) {
void board_init(void) {
__disable_irq();
// double tap use backup register: enable PWR and BKP clock, and BKP write enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, ENABLE);
PWR->CTLR |= PWR_CTLR_DBP;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure = {

View file

@ -29,9 +29,12 @@
extern "C" {
#endif
#include "ch32v20x.h"
#include "board.h"
#define TINYUF2_DBL_TAP_DFU 1
#define TINYUF2_DBL_TAP_DFU 1
#define TINYUF2_DBL_TAP_REG BKP->DATAR10
#define TINYUF2_DBL_TAP_REG_SIZE 16
// symbol from linker
extern uint32_t __flash_size[];

View file

@ -30,6 +30,20 @@
#include <string.h>
#include "boards.h"
//--------------------------------------------------------------------+
// Compiler
//--------------------------------------------------------------------+
#define TUF2_TOKEN(x) x
#define TUF2_STRING(x) #x // stringify without expand
#define TUF2_XSTRING(x) TU_STRING(x) // expand then stringify
#define TUF2_STRCAT(a, b) a##b // concat without expand
#define TUF2_STRCAT3(a, b, c) a##b##c // concat without expand
#define TUF2_XSTRCAT(a, b) TU_STRCAT(a, b) // expand then concat
#define TUF2_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) // expand then concat 3 tokens
#define ATTR_WEAK __attribute__ ((weak))
#define ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
@ -46,6 +60,11 @@
#define BOARD_FLASH_APP_START 0
#endif
#ifndef TUF2_LOG
#define TUF2_LOG 2
#endif
// Use LED for part of indicator
#ifndef TINYUF2_LED
#define TINYUF2_LED 0
@ -61,10 +80,8 @@
#define TINYUF2_DBL_TAP_DELAY 500
#endif
#ifndef TINYUF2_DBL_TAP_REG
// defined by linker script
extern uint32_t _board_dfu_dbl_tap[];
#define TINYUF2_DBL_TAP_REG _board_dfu_dbl_tap[0]
#ifndef TINYUF2_DBL_TAP_REG_SIZE
#define TINYUF2_DBL_TAP_REG_SIZE 32
#endif
// Use Display to draw DFU image
@ -82,10 +99,6 @@ extern uint32_t _board_dfu_dbl_tap[];
#define TINYUF2_CONST
#endif
#ifndef TUF2_LOG
#define TUF2_LOG 2
#endif
// Use favicon.ico + autorun.inf (only works with windows)
// define TINYUF2_FAVICON_HEADER to enable this feature
@ -93,9 +106,26 @@ extern uint32_t _board_dfu_dbl_tap[];
// Constant
//--------------------------------------------------------------------+
#define DBL_TAP_MAGIC 0xf01669ef // Enter DFU magic
#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef // Skip double tap delay detection
#define DBL_TAP_MAGIC_ERASE_APP 0xf5e80ab4 // Erase entire application !!
// defined by linker script
#if TINYUF2_DBL_TAP_REG_SIZE == 32
#define DBL_TAP_TYPE uint32_t
#elif TINYUF2_DBL_TAP_REG_SIZE == 16
#define DBL_TAP_TYPE uint16_t
#elif TINYUF2_DBL_TAP_REG_SIZE == 8
#define DBL_TAP_TYPE uint8_t
#else
#error "Invalid TINYUF2_DBL_TAP_REG_SIZE"
#endif
#ifndef TINYUF2_DBL_TAP_REG
// defined by linker script
extern DBL_TAP_TYPE _board_dfu_dbl_tap[];
#define TINYUF2_DBL_TAP_REG _board_dfu_dbl_tap[0]
#endif
#define DBL_TAP_MAGIC (0xf01669ef >> (32 - TINYUF2_DBL_TAP_REG_SIZE)) // Enter DFU magic
#define DBL_TAP_MAGIC_QUICK_BOOT (0xf02669ef >> (32 - TINYUF2_DBL_TAP_REG_SIZE)) // Skip double tap delay detection
#define DBL_TAP_MAGIC_ERASE_APP (0xf5e80ab4 >> (32 - TINYUF2_DBL_TAP_REG_SIZE)) // Erase entire application !!
//--------------------------------------------------------------------+
// Basic API
@ -233,7 +263,7 @@ void board_self_update(const uint8_t * bootloader_bin, uint32_t bootloader_len);
#define TUF2_LOG1_MEM // tu_print_mem
#define TUF2_LOG1_VAR(_x) // tu_print_var((uint8_t const*)(_x), sizeof(*(_x)))
#define TUF2_LOG1_INT(_x) tuf2_printf(#_x " = %ld\r\n", (uint32_t) (_x) )
#define TUF2_LOG1_HEX(_x) tuf2_printf(#_x " = %lX\r\n", (uint32_t) (_x) )
#define TUF2_LOG1_HEX(_x) tuf2_printf(#_x " = 0x%lX\r\n", (uint32_t) (_x) )
#define TUF2_LOG1_LOCATION() tuf2_printf("%s: %d:\r\n", __PRETTY_FUNCTION__, __LINE__)
#define TUF2_LOG1_FAILED() tuf2_printf("%s: %d: Failed\r\n", __PRETTY_FUNCTION__, __LINE__)

View file

@ -93,34 +93,41 @@ int main(void) {
// return true if start DFU mode, else App mode
static bool check_dfu_mode(void) {
// Check if app is valid
if (!board_app_valid()) return true;
if (board_app_valid2 && !board_app_valid2()) return true;
if (!board_app_valid()) {
TUF2_LOG1("App invalid\r\n");
return true;
}
if (board_app_valid2 && !board_app_valid2()) {
TUF2_LOG1("App invalid\r\n");
return true;
}
#if TINYUF2_DBL_TAP_DFU
TUF2_LOG1_HEX(&TINYUF2_DBL_TAP_REG);
TUF2_LOG1_HEX(TINYUF2_DBL_TAP_REG);
// Erase application
if (TINYUF2_DBL_TAP_REG == DBL_TAP_MAGIC_ERASE_APP) {
TINYUF2_DBL_TAP_REG = 0;
switch(TINYUF2_DBL_TAP_REG) {
case DBL_TAP_MAGIC_QUICK_BOOT:
// Boot to app quickly
TUF2_LOG1("Quick boot to App\r\n");
TINYUF2_DBL_TAP_REG = 0;
return false;
indicator_set(STATE_WRITING_STARTED);
board_flash_erase_app();
indicator_set(STATE_WRITING_FINISHED);
case DBL_TAP_MAGIC:
// Double tap occurred
TUF2_LOG1("Double Tap Reset\r\n");
TINYUF2_DBL_TAP_REG = 0;
return true;
return true;
}
case DBL_TAP_MAGIC_ERASE_APP:
TUF2_LOG1("Erase app\r\n");
TINYUF2_DBL_TAP_REG = 0;
indicator_set(STATE_WRITING_STARTED);
board_flash_erase_app();
indicator_set(STATE_WRITING_FINISHED);
return true;
// App want to reboot quickly
if (TINYUF2_DBL_TAP_REG == DBL_TAP_MAGIC_QUICK_BOOT) {
TINYUF2_DBL_TAP_REG = 0;
return false;
}
if (TINYUF2_DBL_TAP_REG == DBL_TAP_MAGIC) {
// Double tap occurred
TINYUF2_DBL_TAP_REG = 0;
TU_LOG1("Double Tap Reset\r\n");
return true;
default:
break;
}
// Register our first reset for double reset detection