Files
@ c0c52bad69d7
Branch filter:
Location: therm/flash.c
c0c52bad69d7
4.3 KiB
text/plain
Initial work on flash stuff. Reads and writes weird values...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | #include "stm32f0xx_hal.h"
#include "ssd1306.h"
#include "stm32f0xx_hal_flash.h"
#include "flash.h"
void flash_init(therm_settings_t* tosave)
{
uint16_t size = sizeof(therm_settings_t)-1;
uint32_t flash_adr = END_ADDR - size;
flash_adr -= 2;
uint8_t* flash_ptr = (uint8_t *)flash_adr;
// Check if flash is blank
uint16_t i = 0;
uint16_t count = 0;
char tempstr[10];
itoa(flash_adr, tempstr, 10);
ssd1306_DrawString(tempstr, 1, 0);
uint16_t test;
for(i=0;i<size;i++)
{
test = *flash_ptr;
if(test==0xFF) count++;
}
ssd1306_DrawString("END LOOP ", 0, 0);
// If blank, do nothing and just use values from RAM
// If not blank, check the checksums
if(count != size)
{
ssd1306_DrawString("FLASH NOT BLANK", 1, 0);
// Calculate Checksums
uint8_t cksum0=0,cksum1=0;
uint8_t rdSum0=0,rdSum1=0;
flash_adr = END_ADDR - size;
flash_ptr = (uint8_t *)flash_adr;
for(i=1; i < size; i++)
{
cksum0 += *flash_ptr++;
cksum1 += cksum0;
}
// Read flash checksums
flash_adr -= 2;
flash_ptr = (uint8_t *)flash_adr;
rdSum0 = *flash_ptr++;
rdSum1 = *flash_ptr;
// Compare Checksums values
if((rdSum1==cksum1)&&(rdSum0==cksum0)) {
ssd1306_DrawString("CHECKSUM OK", 2, 0);
flash_read(tosave);
}
else {
ssd1306_DrawString("CHECKSUM BAD", 2, 0);
return; // If the checksum is bad, just use vals from RAM
}
}
else {
ssd1306_DrawString("FLASH BLANK", 1, 0);
}
}
void flash_save(therm_settings_t* tosave)
{
ssd1306_DrawString("BEGIN SAVE", 2, 0);
HAL_Delay(1500);
flash_erase(tosave);
flash_write(tosave);
flash_checksum(tosave);
ssd1306_DrawString("END SAVE", 2, 0);
HAL_Delay(1500);
}
void flash_read(therm_settings_t *tosave)
{
ssd1306_DrawString("READING SAVE", 1, 0);
char tempstr[10];
itoa(sizeof(therm_settings_t), tempstr, 10);
ssd1306_DrawString(tempstr, 2, 0);
uint16_t size = sizeof(therm_settings_t)-1; // in Bytes
uint32_t flash_adr = END_ADDR - size;
uint8_t *flash_ptr = (uint8_t *)flash_adr;
uint8_t *struct_ptr = (uint8_t*)tosave;
uint16_t i;
for(i=0;i<size;i++)
*struct_ptr++ = *flash_ptr++;
ssd1306_DrawString("READ COMPLETE", 3, 0);
}
void flash_write(therm_settings_t* tosave)
{
HAL_FLASH_Unlock();
uint16_t size = sizeof(therm_settings_t)-1; // in Bytes
uint32_t start_address = END_ADDR-size; // write to end of page
uint32_t struct_ptr = (uint32_t*) tosave;
uint16_t length;
if(size%2==0)
length = size/2;
else
length = size/2+1;
uint16_t i;
for(i=0;i<length;i++)
{
HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, start_address, struct_ptr);
struct_ptr++;
start_address +=2;
}
HAL_FLASH_Lock();
}
void flash_checksum(therm_settings_t* tosave)
{
uint8_t cksum0=0,cksum1=0;
uint16_t i,size,checksum;
uint32_t flash_adr;
uint8_t *flash_ptr;
HAL_FLASH_Unlock();
size = sizeof(*tosave)-1; // in Bytes
flash_adr = END_ADDR-size;
flash_ptr = (uint8_t *)flash_adr;
for(i=1; i < size; i++)
{
cksum0 += *flash_ptr++;
cksum1 += cksum0;
}
checksum = (cksum1<<8) | cksum0;
flash_adr -= 2;
HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, flash_adr, checksum);
HAL_FLASH_Lock();
}
void flash_erase(therm_settings_t* tosave)
{
uint8_t FLASHStatus = 1; // FLASH_COMPLETE=1
uint32_t end_addr = END_ADDR;
uint32_t NbrOfPage = abs( (sizeof(*tosave)-1)/0x400 )+1; // Number of pages to be erased, most definitely 1 but hey, we might as well try to calculate it.
uint32_t StartAddr = (end_addr+1) - (0x400*NbrOfPage); // Starting address to be erased
HAL_FLASH_Unlock();
// Clear All pending flags
//FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
// Erase the FLASH pages
FLASH_EraseInitTypeDef erase;
erase.TypeErase = TYPEERASE_PAGES;
erase.PageAddress = StartAddr;
erase.NbPages = NbrOfPage;
uint32_t SectorError = 0;
FLASHStatus = HAL_FLASHEx_Erase(&erase, &SectorError);
HAL_FLASH_Lock();
}
// vim:softtabstop=4 shiftwidth=4 expandtab
|