Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // flash.c
- // STM32F4xx
- // teplofizik
- // ******************************************************
- #include "flash.h"
- #include <stm32f4xx.h>
- #include <string.h>
- typedef struct
- {
- uint32_t From;
- uint32_t To;
- uint8_t Sector;
- } TSector;
- // 1 MB памяти
- static const TSector Sectors[] = {
- // STM32F40x, STM32F41x, STM32F42x, STM32F43x
- { 0x08000000UL, 0x08003FFFUL, 0 }, // 16 kB
- { 0x08004000UL, 0x08007FFFUL, 1 }, // 16 kB
- { 0x08008000UL, 0x0800BFFFUL, 2 }, // 16 kB
- { 0x0800C000UL, 0x0800FFFFUL, 3 }, // 16 kB
- { 0x08010000UL, 0x0801FFFFUL, 4 }, // 64 kB
- { 0x08020000UL, 0x0803FFFFUL, 5 }, // 128 kB
- { 0x08040000UL, 0x0805FFFFUL, 6 }, // 128 kB
- { 0x08060000UL, 0x0807FFFFUL, 7 }, // 128 kB
- { 0x08080000UL, 0x0809FFFFUL, 8 }, // 128 kB
- { 0x080A0000UL, 0x080BFFFFUL, 9 }, // 128 kB
- { 0x080C0000UL, 0x080DFFFFUL, 10 }, // 128 kB
- { 0x080E0000UL, 0x080FFFFFUL, 11 }, // 128 kB
- // STM32F42x, STM32F43x
- // 2 Мб
- // ...
- };
- static const int SectorCount = sizeof(Sectors) / sizeof(Sectors[0]);
- static int8_t GetSectorIndex(void * Address)
- {
- int i;
- for(i = 0; i < SectorCount; i++)
- {
- if((Sectors[i].From <= (uint32_t)Address) && ((Sectors[i].To >= (uint32_t)Address))) return Sectors[i].Sector;
- }
- // Не найдено
- return -1;
- }
- // Разблокировка доступа ко Flash
- static void flash_Unlock(void)
- {
- FLASH->KEYR = 0x45670123;
- FLASH->KEYR = 0xCDEF89AB;
- }
- // Блокировка доступа ко Flash
- static void flash_Lock(void)
- {
- FLASH->CR |= FLASH_CR_LOCK;
- }
- // Очистить сектор
- static void flash_ClearSector(uint8_t Index)
- {
- if(Index >= SectorCount) return;
- flash_Unlock();
- // Ждм готовности
- while(FLASH->SR & FLASH_SR_BSY) {}
- // Выбираем номер сектора (SNB) и флаг, что хотим чистить (SER)
- {
- uint32_t Temp = FLASH->CR;
- Temp &= ~(0xFUL << 3); // FLASH_CR_SNB [3:6]
- Temp |= (Index << 3);
- Temp |= FLASH_CR_SER;
- FLASH->CR = Temp;
- }
- // Запуск!
- FLASH->CR |= FLASH_CR_STRT;
- // Ждм завершения операций с флешем
- while(FLASH->SR & FLASH_SR_BSY) {}
- // Сбрасываем флаг, что хотим чистить сектор
- FLASH->CR &= ~FLASH_CR_SER;
- flash_Lock();
- }
- void flash_Init(void)
- {
- // Настрйока WAIT STATE при доступе ко FLASH и типа того выполняется в system_stm32f4xx.c
- // Настроим количество ячеек, стираемых за раз (зависит от напряжения)
- // PSIZE(1:0) = 0b10 (32 bits)
- uint32_t Temp;
- flash_Unlock();
- Temp = FLASH->CR;
- Temp &= ~(FLASH_CR_PSIZE_0 | FLASH_CR_PSIZE_1);
- Temp |= FLASH_CR_PSIZE_1;
- FLASH->CR = Temp;
- flash_Lock();
- }
- // Очистка памяти перед записью
- void flash_Erase(void * From, void * To)
- {
- int FromSector = GetSectorIndex(From);
- int ToSector = GetSectorIndex(To);
- int i;
- for(i = FromSector; i <= ToSector; i++) flash_ClearSector(i);
- }
- // Читаем
- void flash_Read(void * Dest, const void * Address, uint32_t Length)
- {
- memcpy(Dest, Address, Length);
- }
- // Записываем
- void flash_Write(const void * Src, void * Address, uint32_t Length)
- {
- flash_Unlock();
- // Ждм готовности
- while(FLASH->SR & FLASH_SR_BSY) {}
- // Ставим флаг, что хотим программировать (PG)
- FLASH->CR |= FLASH_CR_PG;
- // Пишем по 4 байта за раз, так кк выбрали такой способ доступа
- {
- uint32_t * S = (uint32_t *)Src;
- uint32_t * D = (uint32_t *)Address;
- uint32_t L = (Length / sizeof(uint32_t)) + 1;
- uint32_t i;
- for(i = 0; i < L; i++)
- {
- D[i] = S[i];
- // Ждм завершения операций с флешем
- while(FLASH->SR & FLASH_SR_BSY) {}
- }
- }
- // Сбрасываем флаг, что хотим программировать (PG)
- FLASH->CR &= ~FLASH_CR_PG;
- flash_Lock();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement