Testing FlashIAP library with MBED OS 6 and sleep functions

Committer:
mmdonatti
Date:
Tue Aug 11 17:07:42 2020 +0000
Revision:
2:d43334a39b02
Parent:
1:1fbedf72d2a6
circular buffer implemented, using Flash pages and sectors

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mmdonatti 1:1fbedf72d2a6 1 /*********************************************************************
mmdonatti 1:1fbedf72d2a6 2 *
mmdonatti 1:1fbedf72d2a6 3 * FlashIAP (In-Application Programming) Test - MBED OS 6.2
mmdonatti 1:1fbedf72d2a6 4 *
mmdonatti 1:1fbedf72d2a6 5 * Mauricio Martins Donatti
mmdonatti 1:1fbedf72d2a6 6 * mauricio.donatti@lnls.br
mmdonatti 1:1fbedf72d2a6 7 *
mmdonatti 1:1fbedf72d2a6 8 * Electronics Instrumentation Group - GIE
mmdonatti 1:1fbedf72d2a6 9 * Brazilian Synchrotron Light Laboratory (LNLS)
mmdonatti 1:1fbedf72d2a6 10 * Brazilian Center for Research in Energy and Materials (CNPEM)
mmdonatti 1:1fbedf72d2a6 11 *
mmdonatti 1:1fbedf72d2a6 12 * August 2020
mmdonatti 1:1fbedf72d2a6 13 *
mmdonatti 1:1fbedf72d2a6 14 *
mmdonatti 1:1fbedf72d2a6 15 *******************************************************************/
mmdonatti 0:48a28b2443d1 16
mmdonatti 0:48a28b2443d1 17 #include "mbed.h"
mmdonatti 0:48a28b2443d1 18
mmdonatti 2:d43334a39b02 19 #define FLASH_DEBUG
mmdonatti 2:d43334a39b02 20
mmdonatti 2:d43334a39b02 21 #ifdef FLASH_DEBUG
mmdonatti 2:d43334a39b02 22 #define FLASH_PRINTF(fmt, ...) pc.printf("FLASH: " fmt "\r\n", ##__VA_ARGS__)
mmdonatti 2:d43334a39b02 23 #else
mmdonatti 2:d43334a39b02 24 #define FLASH_PRINTF(fmt, ...) __NOP()
mmdonatti 2:d43334a39b02 25 #endif //Config enabled DEBUG
mmdonatti 2:d43334a39b02 26
mmdonatti 2:d43334a39b02 27 // Time definitions
mmdonatti 0:48a28b2443d1 28 #define SLEEP_DELAY 10
mmdonatti 0:48a28b2443d1 29 #define HEARTBEAT_DELAY 1
mmdonatti 0:48a28b2443d1 30
mmdonatti 2:d43334a39b02 31 //LPC1768 has two sector sizes (4kB and 32kB)
mmdonatti 2:d43334a39b02 32 #define SIZE_4KB 0x1000
mmdonatti 2:d43334a39b02 33 #define SIZE_32KB 0x8000
mmdonatti 2:d43334a39b02 34
mmdonatti 2:d43334a39b02 35 // 4kB Sectors
mmdonatti 2:d43334a39b02 36 #define BLOCK_0x00000_0x00FFF 0x00000
mmdonatti 2:d43334a39b02 37 #define BLOCK_0x01000_0x01FFF 0x01000
mmdonatti 2:d43334a39b02 38 #define BLOCK_0x02000_0x02FFF 0x02000
mmdonatti 2:d43334a39b02 39 #define BLOCK_0x03000_0x03FFF 0x03000
mmdonatti 2:d43334a39b02 40 #define BLOCK_0x04000_0x04FFF 0x04000
mmdonatti 2:d43334a39b02 41 #define BLOCK_0x05000_0x05FFF 0x05000
mmdonatti 2:d43334a39b02 42 #define BLOCK_0x06000_0x06FFF 0x06000
mmdonatti 2:d43334a39b02 43 #define BLOCK_0x07000_0x07FFF 0x07000
mmdonatti 2:d43334a39b02 44 #define BLOCK_0x08000_0x08FFF 0x08000
mmdonatti 2:d43334a39b02 45 #define BLOCK_0x09000_0x09FFF 0x09000
mmdonatti 2:d43334a39b02 46 #define BLOCK_0x0A000_0x0AFFF 0x0A000
mmdonatti 2:d43334a39b02 47 #define BLOCK_0x0B000_0x0BFFF 0x0B000
mmdonatti 2:d43334a39b02 48 #define BLOCK_0x0C000_0x0CFFF 0x0C000
mmdonatti 2:d43334a39b02 49 #define BLOCK_0x0D000_0x0DFFF 0x0D000
mmdonatti 2:d43334a39b02 50 #define BLOCK_0x0E000_0x0EFFF 0x0E000
mmdonatti 2:d43334a39b02 51 #define BLOCK_0x0F000_0x0FFFF 0x0F000
mmdonatti 2:d43334a39b02 52
mmdonatti 2:d43334a39b02 53 //32kB Sectors
mmdonatti 2:d43334a39b02 54 #define BLOCK_0x10000_0x17FFF 0x10000
mmdonatti 2:d43334a39b02 55 #define BLOCK_0x18000_0x1FFFF 0x18000
mmdonatti 2:d43334a39b02 56 #define BLOCK_0x20000_0x27FFF 0x20000
mmdonatti 2:d43334a39b02 57 #define BLOCK_0x28000_0x2FFFF 0x28000
mmdonatti 2:d43334a39b02 58 #define BLOCK_0x30000_0x37FFF 0x30000
mmdonatti 2:d43334a39b02 59 #define BLOCK_0x38000_0x3FFFF 0x38000
mmdonatti 2:d43334a39b02 60 #define BLOCK_0x40000_0x47FFF 0x40000
mmdonatti 2:d43334a39b02 61 #define BLOCK_0x48000_0x4FFFF 0x48000
mmdonatti 2:d43334a39b02 62 #define BLOCK_0x50000_0x57FFF 0x50000
mmdonatti 2:d43334a39b02 63 #define BLOCK_0x58000_0x5FFFF 0x58000
mmdonatti 2:d43334a39b02 64 #define BLOCK_0x60000_0x67FFF 0x60000
mmdonatti 2:d43334a39b02 65 #define BLOCK_0x68000_0x6FFFF 0x68000
mmdonatti 2:d43334a39b02 66 #define BLOCK_0x70000_0x77FFF 0x70000
mmdonatti 2:d43334a39b02 67 #define BLOCK_0x78000_0x7FFFF 0x78000
mmdonatti 2:d43334a39b02 68
mmdonatti 2:d43334a39b02 69 //Application Definitions
mmdonatti 2:d43334a39b02 70 #define DATA_LENGTH 1 //in bytes
mmdonatti 2:d43334a39b02 71 #define USED_BLOCKS 10 //number of used blocks
mmdonatti 2:d43334a39b02 72 #define BLOCK_SIZE SIZE_32KB //block size
mmdonatti 2:d43334a39b02 73 #define FIRST_BLOCK BLOCK_0x10000_0x17FFF
mmdonatti 2:d43334a39b02 74 #define FLAG 1
mmdonatti 2:d43334a39b02 75 #define DEFAULT_DATA 'e'
mmdonatti 0:48a28b2443d1 76
mmdonatti 0:48a28b2443d1 77 Serial pc(USBTX, USBRX,115200);
mmdonatti 0:48a28b2443d1 78
mmdonatti 0:48a28b2443d1 79 DigitalOut heart(LED1); //LED 1 - heart beat mbed
mmdonatti 0:48a28b2443d1 80 DigitalOut msg_completed(LED2); //LED 1 - heart beat mbed
mmdonatti 0:48a28b2443d1 81
mmdonatti 0:48a28b2443d1 82 Ticker heartbeat; //Define the digital output variable heartbeat as "Ticker"
mmdonatti 0:48a28b2443d1 83 int idx_buffer;
mmdonatti 0:48a28b2443d1 84 char buffer[30];
mmdonatti 0:48a28b2443d1 85
mmdonatti 0:48a28b2443d1 86 char last_value;
mmdonatti 0:48a28b2443d1 87
mmdonatti 0:48a28b2443d1 88 void message_completed();
mmdonatti 0:48a28b2443d1 89 // Heart beat function
mmdonatti 0:48a28b2443d1 90 void beat();
mmdonatti 0:48a28b2443d1 91
mmdonatti 2:d43334a39b02 92 FlashIAP flash;
mmdonatti 2:d43334a39b02 93 uint32_t page_size,sector_size,flash_size;
mmdonatti 2:d43334a39b02 94 uint32_t addr,active_addr;
mmdonatti 2:d43334a39b02 95 char erased_byte;
mmdonatti 2:d43334a39b02 96 int ret,active_block;
mmdonatti 2:d43334a39b02 97
mmdonatti 2:d43334a39b02 98 void init_flash();
mmdonatti 2:d43334a39b02 99 void get_flash_data(char* buffer);
mmdonatti 2:d43334a39b02 100 void save_flash_data(char* buffer);
mmdonatti 2:d43334a39b02 101 char flash_buffer[DATA_LENGTH+1];
mmdonatti 2:d43334a39b02 102
mmdonatti 0:48a28b2443d1 103 int main() {
mmdonatti 0:48a28b2443d1 104 heartbeat.attach(&beat,HEARTBEAT_DELAY); //Attaching the address of the function beat() and the interval HEATTBEAT_DELAY
mmdonatti 0:48a28b2443d1 105 idx_buffer=0;
mmdonatti 0:48a28b2443d1 106
mmdonatti 0:48a28b2443d1 107 //Testing if Flash IAP will break after sleep
mmdonatti 0:48a28b2443d1 108 ThisThread::sleep_for(SLEEP_DELAY);
mmdonatti 0:48a28b2443d1 109
mmdonatti 2:d43334a39b02 110 init_flash();
mmdonatti 2:d43334a39b02 111 get_flash_data(&last_value);
mmdonatti 2:d43334a39b02 112 FLASH_PRINTF("Reading last value using Flash IAP: %c",last_value);
mmdonatti 0:48a28b2443d1 113
mmdonatti 0:48a28b2443d1 114 while(1) {
mmdonatti 0:48a28b2443d1 115 if(pc.readable())
mmdonatti 0:48a28b2443d1 116 {
mmdonatti 0:48a28b2443d1 117 buffer[idx_buffer] = pc.getc(); //Saving the character pressed in the rcv_buffer
mmdonatti 0:48a28b2443d1 118 if(buffer[idx_buffer] == '\r'){ //If the key is "ENTER"
mmdonatti 0:48a28b2443d1 119 message_completed(); //Calling message treatment function
mmdonatti 0:48a28b2443d1 120 idx_buffer = 0;
mmdonatti 0:48a28b2443d1 121 }
mmdonatti 0:48a28b2443d1 122 else
mmdonatti 0:48a28b2443d1 123 idx_buffer++; //Increment the index variable
mmdonatti 0:48a28b2443d1 124 }
mmdonatti 0:48a28b2443d1 125 ThisThread::sleep_for(SLEEP_DELAY);
mmdonatti 0:48a28b2443d1 126 }
mmdonatti 0:48a28b2443d1 127 }
mmdonatti 0:48a28b2443d1 128
mmdonatti 2:d43334a39b02 129 void write_flash(char *buffer,int){
mmdonatti 2:d43334a39b02 130
mmdonatti 2:d43334a39b02 131
mmdonatti 2:d43334a39b02 132 }
mmdonatti 2:d43334a39b02 133
mmdonatti 2:d43334a39b02 134 void init_flash(){
mmdonatti 2:d43334a39b02 135 char aux;
mmdonatti 2:d43334a39b02 136
mmdonatti 2:d43334a39b02 137 flash.init();
mmdonatti 2:d43334a39b02 138
mmdonatti 2:d43334a39b02 139 FLASH_PRINTF("\r\n");
mmdonatti 2:d43334a39b02 140 FLASH_PRINTF("--------------------Flash IAP Test - LPC1768 512kB--------------------");
mmdonatti 2:d43334a39b02 141 flash_size = flash.get_flash_size();
mmdonatti 2:d43334a39b02 142 FLASH_PRINTF("Flash Size: 0x%.8x",flash_size);
mmdonatti 2:d43334a39b02 143
mmdonatti 2:d43334a39b02 144 addr = flash.get_flash_start();
mmdonatti 2:d43334a39b02 145 FLASH_PRINTF("Flash Start: 0x%.8x",addr);
mmdonatti 2:d43334a39b02 146
mmdonatti 2:d43334a39b02 147 page_size = flash.get_page_size();
mmdonatti 2:d43334a39b02 148 FLASH_PRINTF("Page Size: 0x%.8x",page_size);
mmdonatti 2:d43334a39b02 149
mmdonatti 2:d43334a39b02 150 FLASH_PRINTF("\r\n");
mmdonatti 2:d43334a39b02 151 FLASH_PRINTF("--------------------Flash Memory Mapping--------------------");
mmdonatti 2:d43334a39b02 152 FLASH_PRINTF("Start Address\tSector Size");
mmdonatti 2:d43334a39b02 153 do{
mmdonatti 2:d43334a39b02 154 sector_size = flash.get_sector_size(addr);
mmdonatti 2:d43334a39b02 155 FLASH_PRINTF("0x%.8x\t0x%.8x",addr,sector_size);
mmdonatti 2:d43334a39b02 156 addr = addr + sector_size;
mmdonatti 2:d43334a39b02 157
mmdonatti 2:d43334a39b02 158 }while(addr < flash_size);
mmdonatti 2:d43334a39b02 159
mmdonatti 2:d43334a39b02 160 FLASH_PRINTF("------------------------------------------------------------");
mmdonatti 2:d43334a39b02 161 FLASH_PRINTF("\r\n");
mmdonatti 2:d43334a39b02 162
mmdonatti 2:d43334a39b02 163 erased_byte = flash.get_erase_value();
mmdonatti 2:d43334a39b02 164 FLASH_PRINTF("Erased Byte Value: 0x%.2X",erased_byte);
mmdonatti 2:d43334a39b02 165 }
mmdonatti 2:d43334a39b02 166
mmdonatti 2:d43334a39b02 167 void get_flash_data(char* buffer){
mmdonatti 2:d43334a39b02 168 char aux;
mmdonatti 2:d43334a39b02 169 int i,j;
mmdonatti 2:d43334a39b02 170 active_addr=0;
mmdonatti 2:d43334a39b02 171 for(i=0;i<USED_BLOCKS && active_addr==0;i++){
mmdonatti 2:d43334a39b02 172 ret = flash.read(&aux,FIRST_BLOCK+i*BLOCK_SIZE,1);
mmdonatti 2:d43334a39b02 173 FLASH_PRINTF("Returned %d - Reading 0x%0.8X: 0x%02X\t%c",ret,FIRST_BLOCK+i*BLOCK_SIZE,aux,aux);
mmdonatti 2:d43334a39b02 174 if(aux==erased_byte)
mmdonatti 2:d43334a39b02 175 FLASH_PRINTF("block %d is new",i);
mmdonatti 2:d43334a39b02 176 else{
mmdonatti 2:d43334a39b02 177 ret = flash.read(&aux,FIRST_BLOCK+(i+1)*BLOCK_SIZE-page_size,1);
mmdonatti 2:d43334a39b02 178 if(aux==erased_byte){
mmdonatti 2:d43334a39b02 179 FLASH_PRINTF("block %d is not full",i);
mmdonatti 2:d43334a39b02 180 active_block = i;
mmdonatti 2:d43334a39b02 181 for(j=0;j<BLOCK_SIZE-page_size;j=j+page_size){
mmdonatti 2:d43334a39b02 182 ret = flash.read(&aux,FIRST_BLOCK+i*BLOCK_SIZE+j,1);
mmdonatti 2:d43334a39b02 183 FLASH_PRINTF("Read Address 0x%.8x: %.02X",FIRST_BLOCK+i*BLOCK_SIZE+j,aux);
mmdonatti 2:d43334a39b02 184 if(aux==FLAG){
mmdonatti 2:d43334a39b02 185 FLASH_PRINTF("Block %d Address: 0x%.8x is used",i,FIRST_BLOCK+i*BLOCK_SIZE+j);
mmdonatti 2:d43334a39b02 186 }
mmdonatti 2:d43334a39b02 187 else{
mmdonatti 2:d43334a39b02 188 active_block = i;
mmdonatti 2:d43334a39b02 189 active_addr = FIRST_BLOCK+active_block*BLOCK_SIZE+j;
mmdonatti 2:d43334a39b02 190 ret = flash.read(buffer,active_addr-page_size+1,DATA_LENGTH);
mmdonatti 2:d43334a39b02 191 FLASH_PRINTF("Block %d Address: 0x%.8x Returned %d - Reading last value using Flash IAP: 0x%02X\t%c",i,active_addr-page_size,ret,last_value,last_value);
mmdonatti 2:d43334a39b02 192 break;
mmdonatti 2:d43334a39b02 193 }
mmdonatti 2:d43334a39b02 194 }
mmdonatti 2:d43334a39b02 195 }
mmdonatti 2:d43334a39b02 196 else{
mmdonatti 2:d43334a39b02 197 FLASH_PRINTF("block %d is full",i);
mmdonatti 2:d43334a39b02 198
mmdonatti 2:d43334a39b02 199 }
mmdonatti 2:d43334a39b02 200 }
mmdonatti 2:d43334a39b02 201 }
mmdonatti 2:d43334a39b02 202 if(active_addr==0){
mmdonatti 2:d43334a39b02 203 active_block = 0;
mmdonatti 2:d43334a39b02 204 active_addr = FIRST_BLOCK+active_block*BLOCK_SIZE;
mmdonatti 2:d43334a39b02 205 FLASH_PRINTF("All Blocks are new: using block %d at address 0x%.8x",active_block,active_addr);
mmdonatti 2:d43334a39b02 206 }
mmdonatti 2:d43334a39b02 207 }
mmdonatti 2:d43334a39b02 208
mmdonatti 2:d43334a39b02 209 void save_flash_data(char* buffer){
mmdonatti 2:d43334a39b02 210 char aux;
mmdonatti 2:d43334a39b02 211 int i;
mmdonatti 2:d43334a39b02 212 aux = FLAG;
mmdonatti 2:d43334a39b02 213 flash_buffer[0] = FLAG;
mmdonatti 2:d43334a39b02 214 for(i=0;i<DATA_LENGTH;i++)
mmdonatti 2:d43334a39b02 215 flash_buffer[i+1]=buffer[i];
mmdonatti 2:d43334a39b02 216
mmdonatti 2:d43334a39b02 217 if(active_addr+page_size<FIRST_BLOCK+(active_block+1)*BLOCK_SIZE-1){ //If current block is not full
mmdonatti 2:d43334a39b02 218 ret = flash.program(flash_buffer,active_addr,DATA_LENGTH+1);
mmdonatti 2:d43334a39b02 219 FLASH_PRINTF("Returned %d - Saving Data to address 0x%0.8X",ret,active_addr+1);
mmdonatti 2:d43334a39b02 220 active_addr = active_addr+page_size;
mmdonatti 2:d43334a39b02 221 FLASH_PRINTF("Saving new data to bank %d and address 0x%0.8X",active_block,active_addr);
mmdonatti 2:d43334a39b02 222 }
mmdonatti 2:d43334a39b02 223 else{ //If current block is full
mmdonatti 2:d43334a39b02 224 FLASH_PRINTF("block %d is full",active_block);
mmdonatti 2:d43334a39b02 225 int new_bank;
mmdonatti 2:d43334a39b02 226 new_bank = (active_block+1)%USED_BLOCKS; //Next Flash Bank
mmdonatti 2:d43334a39b02 227 FLASH_PRINTF("erasing block %d",new_bank);
mmdonatti 2:d43334a39b02 228 ret = flash.erase(FIRST_BLOCK+new_bank*BLOCK_SIZE,sector_size); //Erase new bank
mmdonatti 2:d43334a39b02 229 ret = flash.program(flash_buffer,FIRST_BLOCK+new_bank*BLOCK_SIZE,DATA_LENGTH+1);
mmdonatti 2:d43334a39b02 230 FLASH_PRINTF("Saving new data to bank %d and address 0x%0.8X",new_bank,FIRST_BLOCK+new_bank*BLOCK_SIZE);
mmdonatti 2:d43334a39b02 231
mmdonatti 2:d43334a39b02 232 FLASH_PRINTF("Programming old block %d as obsolete",active_block);
mmdonatti 2:d43334a39b02 233 ret = flash.program(&aux,FIRST_BLOCK+(active_block+1)*BLOCK_SIZE-page_size,1);
mmdonatti 2:d43334a39b02 234 FLASH_PRINTF("Returned %d - Saving Data to address 0x%0.8X: 0x%02X",ret,FIRST_BLOCK+(active_block+1)*BLOCK_SIZE-page_size,aux);
mmdonatti 2:d43334a39b02 235 active_addr = FIRST_BLOCK+new_bank*BLOCK_SIZE+page_size;
mmdonatti 2:d43334a39b02 236 active_block = new_bank;
mmdonatti 2:d43334a39b02 237 }
mmdonatti 2:d43334a39b02 238 }
mmdonatti 2:d43334a39b02 239
mmdonatti 2:d43334a39b02 240
mmdonatti 0:48a28b2443d1 241 void message_completed()
mmdonatti 0:48a28b2443d1 242 {
mmdonatti 0:48a28b2443d1 243 msg_completed = !msg_completed;
mmdonatti 2:d43334a39b02 244 ret = flash.read(&last_value,active_addr-page_size+1,DATA_LENGTH);
mmdonatti 2:d43334a39b02 245 FLASH_PRINTF("Returned %d - Reading last value using Flash IAP: 0x%02X\t%c",ret,last_value,last_value);
mmdonatti 2:d43334a39b02 246 save_flash_data(buffer);
mmdonatti 2:d43334a39b02 247 FLASH_PRINTF("Saving %c using flash IAP",buffer[0]);
mmdonatti 2:d43334a39b02 248 ret = flash.read(&last_value,active_addr-page_size+1,DATA_LENGTH);
mmdonatti 2:d43334a39b02 249 FLASH_PRINTF("Returned %d - Reading last value using Flash IAP: 0x%02X\t%c",ret,last_value,last_value);
mmdonatti 0:48a28b2443d1 250 }
mmdonatti 0:48a28b2443d1 251
mmdonatti 0:48a28b2443d1 252 void beat()
mmdonatti 0:48a28b2443d1 253 {
mmdonatti 0:48a28b2443d1 254 heart = !heart; //Flip the LED 1
mmdonatti 0:48a28b2443d1 255 }
mmdonatti 0:48a28b2443d1 256