Advertisement
teplofizik

flash.c (flash)

Jun 7th, 2013
675
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.49 KB | None | 0 0
  1. //
  2. // flash.c
  3. // STM32F4xx
  4. // teplofizik
  5. // ******************************************************
  6.  
  7. #include "flash.h"
  8. #include <stm32f4xx.h>
  9. #include <string.h>
  10.  
  11. typedef struct
  12. {
  13.     uint32_t From;
  14.     uint32_t To;
  15.    
  16.     uint8_t Sector;
  17. } TSector;
  18.  
  19. // 1 MB памяти
  20. static const TSector Sectors[] = {
  21.     // STM32F40x, STM32F41x, STM32F42x, STM32F43x
  22.     { 0x08000000UL, 0x08003FFFUL,  0 }, // 16 kB
  23.     { 0x08004000UL, 0x08007FFFUL,  1 }, // 16 kB
  24.     { 0x08008000UL, 0x0800BFFFUL,  2 }, // 16 kB
  25.     { 0x0800C000UL, 0x0800FFFFUL,  3 }, // 16 kB
  26.     { 0x08010000UL, 0x0801FFFFUL,  4 }, // 64 kB
  27.     { 0x08020000UL, 0x0803FFFFUL,  5 }, // 128 kB
  28.     { 0x08040000UL, 0x0805FFFFUL,  6 }, // 128 kB
  29.     { 0x08060000UL, 0x0807FFFFUL,  7 }, // 128 kB
  30.     { 0x08080000UL, 0x0809FFFFUL,  8 }, // 128 kB
  31.     { 0x080A0000UL, 0x080BFFFFUL,  9 }, // 128 kB
  32.     { 0x080C0000UL, 0x080DFFFFUL, 10 }, // 128 kB
  33.     { 0x080E0000UL, 0x080FFFFFUL, 11 }, // 128 kB
  34.     // STM32F42x, STM32F43x
  35.     // 2 Мб
  36.     // ...
  37. };
  38.  
  39. static const int SectorCount = sizeof(Sectors) / sizeof(Sectors[0]);
  40.  
  41. static int8_t GetSectorIndex(void * Address)
  42. {
  43.     int i;
  44.    
  45.     for(i = 0; i < SectorCount; i++)
  46.     {
  47.         if((Sectors[i].From <= (uint32_t)Address) && ((Sectors[i].To >= (uint32_t)Address))) return Sectors[i].Sector;
  48.     }
  49.    
  50.     // Не найдено
  51.     return -1;
  52. }
  53.  
  54.  
  55. // Разблокировка доступа ко Flash
  56. static void flash_Unlock(void)
  57. {
  58.     FLASH->KEYR = 0x45670123;
  59.     FLASH->KEYR = 0xCDEF89AB;
  60. }
  61.  
  62. // Блокировка доступа ко Flash
  63. static void flash_Lock(void)
  64. {
  65.     FLASH->CR |= FLASH_CR_LOCK;
  66. }
  67.  
  68. // Очистить сектор
  69. static void flash_ClearSector(uint8_t Index)
  70. {
  71.     if(Index >= SectorCount) return;
  72.    
  73.     flash_Unlock();
  74.    
  75.     // Ждм готовности
  76.     while(FLASH->SR & FLASH_SR_BSY) {}
  77.        
  78.     // Выбираем номер сектора (SNB) и флаг, что хотим чистить (SER)
  79.     {
  80.         uint32_t Temp = FLASH->CR;
  81.    
  82.         Temp &= ~(0xFUL << 3); // FLASH_CR_SNB [3:6]
  83.         Temp |=  (Index << 3);
  84.        
  85.         Temp |= FLASH_CR_SER;
  86.        
  87.         FLASH->CR = Temp;
  88.     }
  89.    
  90.     // Запуск!
  91.     FLASH->CR |= FLASH_CR_STRT;
  92.    
  93.     // Ждм завершения операций с флешем
  94.     while(FLASH->SR & FLASH_SR_BSY) {}
  95.    
  96.     // Сбрасываем флаг, что хотим чистить сектор
  97.     FLASH->CR &= ~FLASH_CR_SER;
  98.        
  99.     flash_Lock();
  100. }
  101.  
  102. void flash_Init(void)
  103. {
  104.     // Настрйока WAIT STATE при доступе ко FLASH и типа того выполняется в system_stm32f4xx.c
  105.    
  106.     // Настроим количество ячеек, стираемых за раз (зависит от напряжения)
  107.     // PSIZE(1:0) = 0b10 (32 bits)
  108.     uint32_t Temp;
  109.  
  110.     flash_Unlock();
  111.    
  112.     Temp = FLASH->CR;
  113.    
  114.     Temp &= ~(FLASH_CR_PSIZE_0 | FLASH_CR_PSIZE_1);
  115.     Temp |=  FLASH_CR_PSIZE_1;
  116.    
  117.     FLASH->CR = Temp;
  118.    
  119.     flash_Lock();
  120. }
  121.  
  122. // Очистка памяти перед записью
  123. void flash_Erase(void * From, void * To)
  124. {
  125.     int FromSector = GetSectorIndex(From);
  126.     int ToSector = GetSectorIndex(To);
  127.     int i;
  128.    
  129.     for(i = FromSector; i <= ToSector; i++) flash_ClearSector(i);
  130. }
  131.  
  132. // Читаем
  133. void flash_Read(void * Dest, const void * Address, uint32_t Length)
  134. {
  135.     memcpy(Dest, Address, Length);
  136. }
  137.  
  138. // Записываем
  139. void flash_Write(const void * Src, void * Address, uint32_t Length)
  140. {
  141.     flash_Unlock();
  142.    
  143.     // Ждм готовности
  144.     while(FLASH->SR & FLASH_SR_BSY) {}
  145.        
  146.     // Ставим флаг, что хотим программировать (PG)
  147.     FLASH->CR |= FLASH_CR_PG;
  148.    
  149.     // Пишем по 4 байта за раз, так кк выбрали такой способ доступа
  150.     {
  151.         uint32_t * S = (uint32_t *)Src;
  152.         uint32_t * D = (uint32_t *)Address;
  153.        
  154.         uint32_t   L = (Length / sizeof(uint32_t)) + 1;
  155.         uint32_t   i;
  156.        
  157.         for(i = 0; i < L; i++)
  158.         {
  159.             D[i] = S[i];
  160.            
  161.             // Ждм завершения операций с флешем
  162.             while(FLASH->SR & FLASH_SR_BSY) {}
  163.         }
  164.     }
  165.    
  166.     // Сбрасываем флаг, что хотим программировать (PG)
  167.     FLASH->CR &= ~FLASH_CR_PG;
  168.        
  169.     flash_Lock();
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement