diff --git a/controller/fw/embed/bootloader/flash.cpp b/controller/fw/embed/bootloader/flash.cpp new file mode 100644 index 0000000..186ae7b --- /dev/null +++ b/controller/fw/embed/bootloader/flash.cpp @@ -0,0 +1,88 @@ +#include "flash.h" + +void flash_unlock(){ + + // Check if flash is locked + if(!(FLASH->CR & FLASH_CR_LOCK)) { + return; // Already unlocked + } + + // Write flash key sequence to unlock + FLASH->KEYR = 0x45670123; // First key + FLASH->KEYR = 0xCDEF89AB; // Second key + +} + +void flash_lock() { + if(FLASH->CR & FLASH_CR_LOCK) { + return; // Already locked + } + FLASH->CR |= FLASH_CR_LOCK; // Lock flash memory +} + +void erase_sector(uint8_t sector){ + + // Wait if flash is busy + while(FLASH_BUSY); + + // Check if flash is locked and unlock if needed + if(FLASH->CR & FLASH_CR_LOCK) { + flash_unlock(); + } + + // Set sector erase bit and sector number + FLASH->CR |= FLASH_CR_SER; + FLASH->CR &= ~FLASH_CR_SNB; + FLASH->CR |= (sector << FLASH_CR_SNB_Pos) & FLASH_CR_SNB_Msk; + + // Start erase + FLASH->CR |= FLASH_CR_STRT; + + // Wait for erase to complete + while(FLASH_BUSY); + + // Clear sector erase bit + FLASH->CR &= ~FLASH_CR_SER; + +} + +void flash_program_word(uint32_t address,uint32_t data,uint32_t byte_len){ + + // Wait if flash is busy + while(FLASH_BUSY); + // Check if flash is locked and unlock if needed + if(FLASH->CR & FLASH_CR_LOCK) { + flash_unlock(); + } + + // Set program bit 32bit programm size and Write data to address + if(byte_len == 1) { + FLASH_8BYTE; + FLASH->CR |= FLASH_CR_PG; + *(volatile uint8_t*)address = (uint8_t)data; + } else { + FLASH_32BYTE; + FLASH->CR |= FLASH_CR_PG; + *(volatile uint32_t*)address = data; + } + + // Wait for programming to complete + while(FLASH_BUSY); + + // Clear program bit + FLASH->CR &= ~FLASH_CR_PG; + +} + +uint8_t flash_read_word(uint32_t address){ + + // Check if address is valid + if(address < FLASH_BASE || address > FLASH_END) { + return 0; + } + + // Read byte from flash memory + return *((volatile uint8_t*)address); + +} + // Wait if flash \ No newline at end of file diff --git a/controller/fw/embed/bootloader/flash.h b/controller/fw/embed/bootloader/flash.h new file mode 100644 index 0000000..c453c98 --- /dev/null +++ b/controller/fw/embed/bootloader/flash.h @@ -0,0 +1,46 @@ +#ifndef FLASH_H_ +#define FLASH_H_ +#include "stm32f446xx.h" + +// Flash sectors for STM32F407 +#define BOOT 0x08000000 // 16KB - Bootloader +#define APP_ADDR 0x08004000 // 16KB - Application +#define SECTOR_2 0x08008000 // 16KB +#define SECTOR_3 0x0800C000 // 16KB +#define SECTOR_4 0x08010000 // 64KB +#define SECTOR_5 0x08020000 // 128KB +#define SECTOR_6 0x08040000 // 128KB +#define SECTOR_7 0x08060000 // 128KB + + +#define FLAG_BOOT (0x08040000 + 4) +// Flash keys for unlocking flash memory +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xCDEF89AB + +//FLASH SET ONE PROGRAMM WORD +#define FLASH_8BYTE FLASH->CR &= ~FLASH_CR_PSIZE & ~FLASH_CR_PSIZE_1 +#define FLASH_32BYTE FLASH->CR |= FLASH_CR_PSIZE | FLASH_CR_PSIZE_0 + +// Flash command bits +#define FLASH_LOCK FLASH->CR |= FLASH_CR_LOCK +#define FLASH_UNLOCK FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2 + + +// Flash status flags +#define FLASH_BUSY (FLASH->SR & FLASH_SR_BSY) +#define FLASH_ERROR (FLASH->SR & (FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR)) + +//for bootloader +typedef void(*pFunction)(void); + +// Function prototypes +void flash_unlock(void); +void flash_lock(void); +void flash_erase_sector(uint8_t sector); +void flash_program_word(uint32_t address, uint32_t data,uint32_t byte_len); +uint8_t flash_read_word(uint32_t address); + + + +#endif /* FLASH_H_ */ diff --git a/controller/fw/embed/bootloader/main.cpp b/controller/fw/embed/bootloader/main.cpp new file mode 100644 index 0000000..8dbced8 --- /dev/null +++ b/controller/fw/embed/bootloader/main.cpp @@ -0,0 +1,110 @@ +#include +#include +//#include "CRC32.h" +#include "flash.h" + +//CRC + + + +// put function declarations here: +STM32_CAN Can(CAN2, DEF); +static CAN_message_t CAN_TX_msg; +static CAN_message_t CAN_inMsg; + +void buff_data_can(size_t len,size_t len_frame) { + uint8_t buff[len] = {0}; + uint32_t buff_32[len / 4] = {0}; + uint32_t bias = 0; + while(Can.read(CAN_inMsg)) { + for(size_t i = 0; i < len_frame; i++,bias++) { + buff[bias] = CAN_inMsg.buf[i]; + /* if data from len no end blink led 5 count and stop programm */ + if(bias >= len){ + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; + GPIOC->MODER |= GPIO_MODER_MODE10_0; + for(int i = 0;i < 5;i++){ + GPIOC->ODR ^= GPIO_ODR_OD10; + HAL_Delay(500); + } + return; + } + } +} + /* from 8byte to 32 byte */ + +for(size_t i = 0; i < len / 4; i++) { + buff_32[i] = (buff[i*4] << 24) | + (buff[i*4 + 1] << 16) | + (buff[i*4 + 2] << 8) | + buff[i*4 + 3]; +} + +/* CRC check */ + + + /* Work with FLASH */ + + +FLASH_UNLOCK; +uint32_t address = (uint32_t)APP_ADDR; +FLASH_32BYTE; +for(size_t i = 0; i < len; i++) { + if(i == 0) { + flash_erase_sector(1); // Erase sector 1 (APP_ADDR) + while(FLASH_BUSY); + } + + flash_program_word(address + (i * 4), buff_32[i],0); + + while(FLASH_BUSY); +} + + + +flash_lock(); + +} + + + + +void setup() { + Serial.setRx(HARDWARE_SERIAL_RX_PIN); + Serial.setTx(HARDWARE_SERIAL_TX_PIN); + Serial.begin(115200); + Can.begin(); + Can.setBaudRate(1000000); + // put your setup code here, to run once: + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; + GPIOC->MODER |= GPIO_MODER_MODE10_0 | GPIO_MODER_MODE11_0;; + GPIOC->ODR |= GPIO_ODR_OD11; +} + +void loop() { + flash_program_word(FLAG_BOOT,1,1); + for(int i = 0; i < 4; i++ ) { + GPIOC->ODR ^= GPIO_ODR_OD11; + HAL_Delay(500); + } + if(FLAG_BOOT == 1){ + while (Can.read(CAN_inMsg)){ + + // buff_data_can(32000,8); + } + + + + /* Go to application */ +volatile uint32_t* appjump = (volatile uint32_t*)APP_ADDR; + +uint32_t msp_start = *(appjump); +uint32_t reset_handler = *(appjump + 1); + +pFunction start = (pFunction)reset_handler; +__set_MSP(msp_start); +start(); + } + // put your main code here, to run repeatedly: +} +