diff --git a/FirmwareMain.cpp b/FirmwareMain.cpp index d11f2cd..01a3b92 100644 --- a/FirmwareMain.cpp +++ b/FirmwareMain.cpp @@ -73,6 +73,8 @@ IO io; void setup() { + io.init(); + serial.start(); } @@ -121,9 +123,68 @@ void loop() // --------------------------------------------------------------------------- // Firmware Entry Point // --------------------------------------------------------------------------- +#include + +#define STM32_CNF_PAGE_ADDR (uint32_t)0x0800FC00 +#define STM32_CNF_PAGE ((uint32_t *)0x0800FC00) +#define STM32_CNF_PAGE_24 24U + +void jumpToBootLoader() +{ + // Disable RCC, set it to default (after reset) settings Internal clock, no PLL, etc. + RCC_DeInit(); + USART_DeInit(USART1); + USART_DeInit(UART5); + + // Disable Systick timer + SysTick->CTRL = 0; + SysTick->LOAD = 0; + SysTick->VAL = 0; + + // Clear Interrupt Enable Register & Interrupt Pending Register + for (uint8_t i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { + NVIC->ICER[i] = 0xFFFFFFFF; + NVIC->ICPR[i] = 0xFFFFFFFF; + } + +#if defined(STM32F10X_MD) + volatile uint32_t addr = 0x1FFFF000; +#endif + + // Update the NVIC's vector + SCB->VTOR = addr; + + void (*SysMemBootJump)(void); + SysMemBootJump = (void (*)(void))(*((uint32_t *)(addr + 4))); + __ASM volatile ("MSR msp, %0" : : "r" (*(uint32_t *)addr) : "sp"); // __set_MSP + SysMemBootJump(); +} int main() { + // does the configuration page contain the request bootloader flag? + if ((STM32_CNF_PAGE[STM32_CNF_PAGE_24] != 0xFFFFFFFFU) && (STM32_CNF_PAGE[STM32_CNF_PAGE_24] != 0x00U)) { + uint8_t bootloadMode = (STM32_CNF_PAGE[STM32_CNF_PAGE_24] >> 8) & 0xFFU; + if ((bootloadMode & 0x20U) == 0x20U) { + // we unfortunately need to discard the configuration area entirely for bootloader mode... + FLASH_Unlock(); + FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); + +#if defined(STM32F4XX) || defined(STM32F7XX) + if (FLASH_EraseSector(STM32_CNF_SECTOR, VoltageRange_3) != FLASH_COMPLETE) { + FLASH_Lock(); + return RSN_FAILED_ERASE_FLASH; + } +#elif defined(STM32F10X_MD) + if (FLASH_ErasePage(STM32_CNF_PAGE_ADDR) != FLASH_COMPLETE) { + FLASH_Lock(); + return RSN_FAILED_ERASE_FLASH; + } +#endif + jumpToBootLoader(); + } + } + setup(); for (;;) diff --git a/IO.cpp b/IO.cpp index 42bb910..1b29071 100644 --- a/IO.cpp +++ b/IO.cpp @@ -33,6 +33,13 @@ IO::IO(): m_txFrequency(DEFAULT_FREQUENCY), m_rfPower(0U), m_gainMode(ADF_GAIN_AUTO) +{ + /* stub */ +} + +/* Initializes the air interface sampler. */ + +void IO::init() { initInt(); diff --git a/IO.h b/IO.h index b28c525..e2065b4 100644 --- a/IO.h +++ b/IO.h @@ -62,6 +62,10 @@ public: */ IO(); + /** + * @brief Initializes the air interface sampler. + */ + void init(); /** * @brief Starts air interface sampler. */ @@ -213,6 +217,11 @@ public: */ void selfTest(); + /** + * @brief + */ + void resetMCU(); + /** * @brief * @param[out] int1 diff --git a/IOSTM.cpp b/IOSTM.cpp index c0c65e4..2f90f6c 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -338,6 +338,25 @@ void IO::getUDID(uint8_t* buffer) /* */ +void IO::resetMCU() +{ + DEBUG1("reset - bye-bye"); + + delayUS(250 * 1000); + + setLEDInt(false); + setCOSInt(false); + setDMRInt(false); + setP25Int(false); + setNXDNInt(false); + + delayUS(250 * 1000); + + NVIC_SystemReset(); +} + +/* */ + void IO::delayBit() { delay_ns(); diff --git a/SerialPort.cpp b/SerialPort.cpp index 0e4f2a8..3e3c0b5 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -178,6 +178,10 @@ void SerialPort::process() } break; + case CMD_RESET_MCU: + io.resetMCU(); + break; + case CMD_SET_BUFFERS: err = setBuffers(m_buffer + 3U, m_len - 3U); if (err == RSN_OK) { diff --git a/SerialPort.h b/SerialPort.h index 7c08b8d..f3a6d55 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -109,6 +109,8 @@ enum DVM_COMMANDS { CMD_FLSH_READ = 0xE0U, //! Read Flash Partition CMD_FLSH_WRITE = 0xE1U, //! Write Flash Partition + CMD_RESET_MCU = 0xEAU, //! Soft Reboot MCU + CMD_DEBUG1 = 0xF1U, //! CMD_DEBUG2 = 0xF2U, //! CMD_DEBUG3 = 0xF3U, //!