Skip to content

Commit

Permalink
Add runtime bootloader switch for STM32
Browse files Browse the repository at this point in the history
  • Loading branch information
kkonradpl committed Jul 28, 2024
1 parent 9d7f2d5 commit ba865a4
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 3 deletions.
78 changes: 78 additions & 0 deletions src/Platform/Stm32/Bootloader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
*
* FM-DX Tuner
* Copyright (C) 2024 Konrad Kosmatka
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#ifdef ARDUINO_ARCH_STM32
#include <tusb.h>
#include <stm32f0xx_hal.h>

void
Platform_Stm32_Bootloader(void)
{
tud_disconnect();

HAL_NVIC_DisableIRQ(PendSV_IRQn);
HAL_NVIC_DisableIRQ(USB_IRQn);
__HAL_RCC_USB_CLK_DISABLE();

HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel2_3_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel4_5_6_7_IRQn);
__HAL_RCC_DMA1_CLK_DISABLE();

HAL_NVIC_DisableIRQ(SPI1_IRQn);
__HAL_RCC_SPI1_CLK_DISABLE();

HAL_NVIC_DisableIRQ(I2C1_IRQn);
__HAL_RCC_I2C1_CLK_DISABLE();

HAL_NVIC_DisableIRQ(USART1_IRQn);
HAL_NVIC_DisableIRQ(USART2_IRQn);
__HAL_RCC_USART1_CLK_DISABLE();
__HAL_RCC_USART2_CLK_DISABLE();

HAL_NVIC_DisableIRQ(EXTI0_1_IRQn);
HAL_NVIC_DisableIRQ(EXTI2_3_IRQn);
HAL_NVIC_DisableIRQ(EXTI4_15_IRQn);
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();

HAL_GPIO_DeInit(GPIOA, 0xFF);
HAL_GPIO_DeInit(GPIOB, 0xFF);
HAL_GPIO_DeInit(GPIOC, 0xFF);
HAL_GPIO_DeInit(GPIOD, 0xFF);

HAL_RCC_DeInit();

SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;

__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();

const uint32_t addr = 0x1FFFC800;
__set_MSP(*(uint32_t *)addr);

/* Jump to System Memory */
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)(addr + 4)));
bootloader();
while(1);
}

#endif /* ARDUINO_ARCH_STM32 */
27 changes: 27 additions & 0 deletions src/Platform/Stm32/Bootloader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
*
* FM-DX Tuner
* Copyright (C) 2024 Konrad Kosmatka
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#ifndef FMDX_TUNER_PLATFORM_STM32_BOOTLOADER_H
#define FMDX_TUNER_PLATFORM_STM32_BOOTLOADER_H
#ifdef ARDUINO_ARCH_STM32

#include <stddef.h>

void Platform_Stm32_Bootloader(void);

#endif /* ARDUINO_ARCH_STM32 */

#endif /* FMDX_TUNER_PLATFORM_STM32_BOOTLOADER_H */
46 changes: 43 additions & 3 deletions src/Platform/Stm32/UsbCdcStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

#ifdef ARDUINO_ARCH_STM32
#include <Arduino.h>
#include <tusb.h>
#include "UsbCdcStream.hpp"
#include "tusb.h"
#include "Bootloader.hpp"

#define BUFF_SIZE 64
uint8_t rxBuff[BUFF_SIZE];
Expand Down Expand Up @@ -101,8 +102,8 @@ UsbCdcStream::readTx(void)
return value;
}

extern "C"
void tud_cdc_rx_cb(uint8_t itf)
extern "C" void
tud_cdc_rx_cb(uint8_t itf)
{
uint8_t value;
while (tud_cdc_n_available(itf))
Expand All @@ -116,6 +117,45 @@ void tud_cdc_rx_cb(uint8_t itf)
}
}

extern "C" void
tud_cdc_line_state_cb(uint8_t itf,
bool dtr,
bool rts)
{
constexpr unsigned long timeout = 500;
constexpr uint8_t count = 5;

static unsigned long timer = 0;
static uint8_t state = 0;

if (state == 0)
{
if (dtr == 1 &&
rts == 0)
{
state = 1;
timer = millis();
}
return;
}

if ((millis() - timer) > timeout)
{
state = 0;
return;
}

if ((dtr == 1 && rts == 0 && state % 2 == 0) ||
(dtr == 0 && rts == 1 && state % 2 == 1))
{
state++;
}

if (state == count)
{
Platform_Stm32_Bootloader();
}
}

UsbCdcStream UsbCdcSerial;

Expand Down

0 comments on commit ba865a4

Please sign in to comment.