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
}