#include "flash.h" #include static uint32_t write_ptr = SECTOR_6; 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; } void flash_write(uint32_t addr, FLASH_RECORD* record){ uint32_t* data = (uint32_t*)record; uint32_t size = FLASH_RECORD_SIZE / 4; //count words in struct // 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 and write data to flash FLASH_32BYTE; FLASH->CR |= FLASH_CR_PG; for(int i = 0;i < size;i++){ *(volatile uint32_t*)(addr + i * 4) = data[i]; } // Clear program bit FLASH->CR &= ~FLASH_CR_PG; flash_lock(); } // Wait if flash bool validate_crc(FLASH_RECORD* crc){ if(crc->crc == 0x6933) return true; return false; } /* read struct from FLASH */ void flash_read(uint32_t addr,FLASH_RECORD* ptr){ uint32_t* flash_ptr = (uint32_t*)addr; uint32_t* dest = (uint32_t*)ptr; for (int i = 0; i < FLASH_RECORD_SIZE / 4; i++) { dest[i] = flash_ptr[i]; } } /* Поиск актуального адреса во флэш памяти */ FLASH_RECORD load_params(){ __disable_irq(); FLASH_RECORD latest = {0}; FLASH_RECORD res; for(uint32_t addr = SECTOR_6;addr < SECTOR_6_END;addr +=FLASH_RECORD_SIZE) { flash_read(addr,&res); if (!validate_crc(&res)) break; /* нашли адрес */ else if(res.data_id == addr_id) { latest = res; } } __enable_irq(); return latest; } /** * @brief Записывает страницу данных во флеш-память * @param data: Указатель на буфер с данными * @param len: Длина данных в байтах (должна быть кратна 4) * @retval bool: true - успех, false - ошибка */ void write_flash_page(const uint8_t* data, uint16_t len) { // Добавлен const flash_unlock(); for (uint16_t i = 0; i < len; i += 4) { uint32_t word; memcpy(&word, &data[i], 4); // Безопасное копирование HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, write_ptr + i, word); } flash_lock(); }