Mauricio Donatti
/
mbed-os-6-FlashIAP
Testing FlashIAP library with MBED OS 6 and sleep functions
main.cpp
- Committer:
- mmdonatti
- Date:
- 2020-08-11
- Revision:
- 2:d43334a39b02
- Parent:
- 1:1fbedf72d2a6
File content as of revision 2:d43334a39b02:
/********************************************************************* * * FlashIAP (In-Application Programming) Test - MBED OS 6.2 * * Mauricio Martins Donatti * mauricio.donatti@lnls.br * * Electronics Instrumentation Group - GIE * Brazilian Synchrotron Light Laboratory (LNLS) * Brazilian Center for Research in Energy and Materials (CNPEM) * * August 2020 * * *******************************************************************/ #include "mbed.h" #define FLASH_DEBUG #ifdef FLASH_DEBUG #define FLASH_PRINTF(fmt, ...) pc.printf("FLASH: " fmt "\r\n", ##__VA_ARGS__) #else #define FLASH_PRINTF(fmt, ...) __NOP() #endif //Config enabled DEBUG // Time definitions #define SLEEP_DELAY 10 #define HEARTBEAT_DELAY 1 //LPC1768 has two sector sizes (4kB and 32kB) #define SIZE_4KB 0x1000 #define SIZE_32KB 0x8000 // 4kB Sectors #define BLOCK_0x00000_0x00FFF 0x00000 #define BLOCK_0x01000_0x01FFF 0x01000 #define BLOCK_0x02000_0x02FFF 0x02000 #define BLOCK_0x03000_0x03FFF 0x03000 #define BLOCK_0x04000_0x04FFF 0x04000 #define BLOCK_0x05000_0x05FFF 0x05000 #define BLOCK_0x06000_0x06FFF 0x06000 #define BLOCK_0x07000_0x07FFF 0x07000 #define BLOCK_0x08000_0x08FFF 0x08000 #define BLOCK_0x09000_0x09FFF 0x09000 #define BLOCK_0x0A000_0x0AFFF 0x0A000 #define BLOCK_0x0B000_0x0BFFF 0x0B000 #define BLOCK_0x0C000_0x0CFFF 0x0C000 #define BLOCK_0x0D000_0x0DFFF 0x0D000 #define BLOCK_0x0E000_0x0EFFF 0x0E000 #define BLOCK_0x0F000_0x0FFFF 0x0F000 //32kB Sectors #define BLOCK_0x10000_0x17FFF 0x10000 #define BLOCK_0x18000_0x1FFFF 0x18000 #define BLOCK_0x20000_0x27FFF 0x20000 #define BLOCK_0x28000_0x2FFFF 0x28000 #define BLOCK_0x30000_0x37FFF 0x30000 #define BLOCK_0x38000_0x3FFFF 0x38000 #define BLOCK_0x40000_0x47FFF 0x40000 #define BLOCK_0x48000_0x4FFFF 0x48000 #define BLOCK_0x50000_0x57FFF 0x50000 #define BLOCK_0x58000_0x5FFFF 0x58000 #define BLOCK_0x60000_0x67FFF 0x60000 #define BLOCK_0x68000_0x6FFFF 0x68000 #define BLOCK_0x70000_0x77FFF 0x70000 #define BLOCK_0x78000_0x7FFFF 0x78000 //Application Definitions #define DATA_LENGTH 1 //in bytes #define USED_BLOCKS 10 //number of used blocks #define BLOCK_SIZE SIZE_32KB //block size #define FIRST_BLOCK BLOCK_0x10000_0x17FFF #define FLAG 1 #define DEFAULT_DATA 'e' Serial pc(USBTX, USBRX,115200); DigitalOut heart(LED1); //LED 1 - heart beat mbed DigitalOut msg_completed(LED2); //LED 1 - heart beat mbed Ticker heartbeat; //Define the digital output variable heartbeat as "Ticker" int idx_buffer; char buffer[30]; char last_value; void message_completed(); // Heart beat function void beat(); FlashIAP flash; uint32_t page_size,sector_size,flash_size; uint32_t addr,active_addr; char erased_byte; int ret,active_block; void init_flash(); void get_flash_data(char* buffer); void save_flash_data(char* buffer); char flash_buffer[DATA_LENGTH+1]; int main() { heartbeat.attach(&beat,HEARTBEAT_DELAY); //Attaching the address of the function beat() and the interval HEATTBEAT_DELAY idx_buffer=0; //Testing if Flash IAP will break after sleep ThisThread::sleep_for(SLEEP_DELAY); init_flash(); get_flash_data(&last_value); FLASH_PRINTF("Reading last value using Flash IAP: %c",last_value); while(1) { if(pc.readable()) { buffer[idx_buffer] = pc.getc(); //Saving the character pressed in the rcv_buffer if(buffer[idx_buffer] == '\r'){ //If the key is "ENTER" message_completed(); //Calling message treatment function idx_buffer = 0; } else idx_buffer++; //Increment the index variable } ThisThread::sleep_for(SLEEP_DELAY); } } void write_flash(char *buffer,int){ } void init_flash(){ char aux; flash.init(); FLASH_PRINTF("\r\n"); FLASH_PRINTF("--------------------Flash IAP Test - LPC1768 512kB--------------------"); flash_size = flash.get_flash_size(); FLASH_PRINTF("Flash Size: 0x%.8x",flash_size); addr = flash.get_flash_start(); FLASH_PRINTF("Flash Start: 0x%.8x",addr); page_size = flash.get_page_size(); FLASH_PRINTF("Page Size: 0x%.8x",page_size); FLASH_PRINTF("\r\n"); FLASH_PRINTF("--------------------Flash Memory Mapping--------------------"); FLASH_PRINTF("Start Address\tSector Size"); do{ sector_size = flash.get_sector_size(addr); FLASH_PRINTF("0x%.8x\t0x%.8x",addr,sector_size); addr = addr + sector_size; }while(addr < flash_size); FLASH_PRINTF("------------------------------------------------------------"); FLASH_PRINTF("\r\n"); erased_byte = flash.get_erase_value(); FLASH_PRINTF("Erased Byte Value: 0x%.2X",erased_byte); } void get_flash_data(char* buffer){ char aux; int i,j; active_addr=0; for(i=0;i<USED_BLOCKS && active_addr==0;i++){ ret = flash.read(&aux,FIRST_BLOCK+i*BLOCK_SIZE,1); FLASH_PRINTF("Returned %d - Reading 0x%0.8X: 0x%02X\t%c",ret,FIRST_BLOCK+i*BLOCK_SIZE,aux,aux); if(aux==erased_byte) FLASH_PRINTF("block %d is new",i); else{ ret = flash.read(&aux,FIRST_BLOCK+(i+1)*BLOCK_SIZE-page_size,1); if(aux==erased_byte){ FLASH_PRINTF("block %d is not full",i); active_block = i; for(j=0;j<BLOCK_SIZE-page_size;j=j+page_size){ ret = flash.read(&aux,FIRST_BLOCK+i*BLOCK_SIZE+j,1); FLASH_PRINTF("Read Address 0x%.8x: %.02X",FIRST_BLOCK+i*BLOCK_SIZE+j,aux); if(aux==FLAG){ FLASH_PRINTF("Block %d Address: 0x%.8x is used",i,FIRST_BLOCK+i*BLOCK_SIZE+j); } else{ active_block = i; active_addr = FIRST_BLOCK+active_block*BLOCK_SIZE+j; ret = flash.read(buffer,active_addr-page_size+1,DATA_LENGTH); 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); break; } } } else{ FLASH_PRINTF("block %d is full",i); } } } if(active_addr==0){ active_block = 0; active_addr = FIRST_BLOCK+active_block*BLOCK_SIZE; FLASH_PRINTF("All Blocks are new: using block %d at address 0x%.8x",active_block,active_addr); } } void save_flash_data(char* buffer){ char aux; int i; aux = FLAG; flash_buffer[0] = FLAG; for(i=0;i<DATA_LENGTH;i++) flash_buffer[i+1]=buffer[i]; if(active_addr+page_size<FIRST_BLOCK+(active_block+1)*BLOCK_SIZE-1){ //If current block is not full ret = flash.program(flash_buffer,active_addr,DATA_LENGTH+1); FLASH_PRINTF("Returned %d - Saving Data to address 0x%0.8X",ret,active_addr+1); active_addr = active_addr+page_size; FLASH_PRINTF("Saving new data to bank %d and address 0x%0.8X",active_block,active_addr); } else{ //If current block is full FLASH_PRINTF("block %d is full",active_block); int new_bank; new_bank = (active_block+1)%USED_BLOCKS; //Next Flash Bank FLASH_PRINTF("erasing block %d",new_bank); ret = flash.erase(FIRST_BLOCK+new_bank*BLOCK_SIZE,sector_size); //Erase new bank ret = flash.program(flash_buffer,FIRST_BLOCK+new_bank*BLOCK_SIZE,DATA_LENGTH+1); FLASH_PRINTF("Saving new data to bank %d and address 0x%0.8X",new_bank,FIRST_BLOCK+new_bank*BLOCK_SIZE); FLASH_PRINTF("Programming old block %d as obsolete",active_block); ret = flash.program(&aux,FIRST_BLOCK+(active_block+1)*BLOCK_SIZE-page_size,1); FLASH_PRINTF("Returned %d - Saving Data to address 0x%0.8X: 0x%02X",ret,FIRST_BLOCK+(active_block+1)*BLOCK_SIZE-page_size,aux); active_addr = FIRST_BLOCK+new_bank*BLOCK_SIZE+page_size; active_block = new_bank; } } void message_completed() { msg_completed = !msg_completed; ret = flash.read(&last_value,active_addr-page_size+1,DATA_LENGTH); FLASH_PRINTF("Returned %d - Reading last value using Flash IAP: 0x%02X\t%c",ret,last_value,last_value); save_flash_data(buffer); FLASH_PRINTF("Saving %c using flash IAP",buffer[0]); ret = flash.read(&last_value,active_addr-page_size+1,DATA_LENGTH); FLASH_PRINTF("Returned %d - Reading last value using Flash IAP: 0x%02X\t%c",ret,last_value,last_value); } void beat() { heart = !heart; //Flip the LED 1 }