I would like to know how to read a flash memory data (NVM) data for KL27 sum-family? what is the FCCOB1-3 Flash Address[23:16] -Address[7:0]?
When write to Flash memory, what is the flash memory address[23:16] -[7:0] should be set to for 64K KL27 chip?
Does the program write could be 4 bytes a time or 1k bytes (whole sector)a time?
The KL27 writes 32 bit words.
The flash write must be executed from RAM, as can not write flash from flash.
Interrupts must be turned off during the write.
See the attached code. Linker script and startup must move the required section to RAM at boot or before use.
There are no special things that need done to read the normal program flash.
The attached code shows how to read the special areas.
Real Soon Now I'm going to write a book with practical examples like this of how to actually use this family of parts.
Hi, Albert,
Regarding your question to read flash, as you know that the flash reading is the same as SRAM, because the Cortex-M0 uses unified address for program and data, it is okay to read it with an address.
for example,
unsigned int * point=0x2000;
unsigned int temp;
temp=*point;
the 32 bits data in addrss 0x2000 is copied to temp variable.
The FCCOB1-3 is a group of register for the FTFA flash module, for example, you want to program a long words to a specific address, in the case, you can write the specic address to the FCCOB1-3, the long words to FCCOB4-B, write command to FCCOB0, then writing 1 to FSTAT[CCIF] will launch a state machine to write flash.
whether you write two bytes or 4 bytes is dependent on the command type in FCCOB0.
Hope it can help you
BR
Xiangjun Rong
Hi Xiangjun,
I have some error in the code in the email before.
Here again my code, please advise.
//program 1 kbyte 256 longword
static uint8_t gCopy1K[1024]; //1K of Flash sector
#define FlashStoreStart (0x00FC00u)
volatile uint32_t *const FLASH_Addr = (volatile uint32_t *)&(FTFA->FCCOB3);
#define Program4Byte 0x06
#define Erase1Sector 0x09
#define Read1sSection 0x01
static uint16_t gFlashOffset;
status_t flash_write(void)//const void *src, size_t nbytes)
{
// In order to write to flash: system must be in Run mode (not Vlpr) and
// interrupts must be disabled.
uint8_t TestByte;
uint16_t Offset=0;
uint8_t status;
__disable_irq();
for(Offset=0; Offset<0x400; Offset+=4) //1024/4 times
{
TestByte =FTFA->FSTAT;
while((FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK)==0){}; //CCIF =1?
if((TestByte & 0x30)>0)FTFA->FSTAT |=0x30; //write '1' to clear
FTFA->FCCOB0 =Program4Byte;
*FLASH_Addr = FlashStoreStart+Offset;
FTFA->FPROT0=0x80; //highest section 2K byte
FTFA->FPROT1=0x00;
FTFA->FPROT2=0x00;
FTFA->FPROT3=0x00;
(FLASH_Addr) =(gCopy1K+Offset); //copy 4 bytes
(FLASH_Addr+1) =(gCopy1KOffset1);
(FLASH_Addr+2) =(gCopy1KOffset2);
(FLASH_Addr+3) =(gCopy1KOffset3);
FTFA->FSTAT |=FTFA_FSTAT_CCIF_MASK; //Start execution
while((FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK) ==0){};
}
FTFA->FPROT0=0x00; // turn off the highest section 2K byte
status=(FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_MGSTAT0_MASK));
__enable_irq();
return status;
}
// and the Erase 1 sector:
status_t Flash_Erase(void) //const void *sec)
{
uint8_t TestByte;
TestByte =FTFA->FSTAT;
while((FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK) ==0){}; //CCIF =1?
if((TestByte & 0x30)>0)FTFA->FSTAT |=0x30; //write '1' to clear
FTFA->FCCOB0 =Erase1Sector;
*FLASH_Addr =FlashStoreStart;
//FTFA->FCCB1 =0x00;
//FTFA->FCCB2 =0xFC;
//FTFA->FCCB3 =0x00;
FTFA->FPROT0=0x80; //highest section 2K byte
FTFA->FPROT1=0x00;
FTFA->FPROT2=0x00;
FTFA->FPROT3=0x00;
FTFA->FSTAT |=FTFA_FSTAT_CCIF_MASK; //Start Erase
while((FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK) ==0){};
FTFA->FCCOB0 =Read1sSection;
*FLASH_Addr =FlashStoreStart;
//FTFA->FCCB1 =0x00;
//FTFA->FCCB2 =0xFC;
//FTFA->FCCB3 =0x00;
FTFA->FCCOB4 =0x00;
FTFA->FCCOB5 =0x01; // 256 longword
FTFA->FCCOB6 =0x00; //Norm margin level
FTFA->FSTAT |=FTFA_FSTAT_CCIF_MASK; //Start
while((FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK) ==0);
if((FTFA->FSTAT & 0x01)!=0)return 1;
else return 0;
}
Than you in advance.
Albert Zhou
Electronics Engineer
Sensorex Corp.
Hi Xiangjun,
Thank you for your reply. It helps me a lot.
I have question for program long word:
1. Should I erase a sector (1024 bytes) first before program longword? And I need turn on one bit of FPROTx for unlock the protection?
2. Should I program whole sector (1024 bytes) at once, Otherwise one address could not program two times?
3. For a 64K KL27Z64XX, where a location is better for 1K bytes of Calibration Storage? Low end 0x400 or 0xFC00?
4. After complete the program longword, should reset FPROTx register?
The following is my code for program 1024 bytes, please advise:
#define FlashStoreStart (0x0000FC00u) //Highest 1K byte
#define Program4Byte 0x06
volatile uint32_t *const FLASH_Addr = (volatile uint32_t *)&(FTFA->FCCOB3); //wake FCC0B1-3 a longword address
static uint8_t gCopy1K[1024];
uint8_t TestByte;
uint16_t Offset;
__disable_irq();
for(Offset=0; Offset<0x400; Offse+4) //1024/4 times
{
TestByte =FTFA->FSTAT;
while(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK ==0); //CCIF =1?
if((TestByte & 0x30)>0)FTFA->FSTAT |=0x30; //write '1' to clear
FTFA->FCCOB0 =Program4Byte;
FLASH_Addr =FlashStoreStart+Offset;
FTFA->FPROT0=0x80; //highest section 2K byte
FTFA->FPROT1=0x00;
FTFA->FPROT2=0x00;
FTFA->FPROT3=0x00;
(FLASH_Addr) =(gCopy1K+Offset); //copy 4 bytes
(FLASH_Addr+1) =(gCopy1KOffset1);
(FLASH_Addr+2) =(gCopy1KOffset2);
(FLASH_Addr+3) =(gCopy1KOffset3);
FTFA->FSTAT |=FTFA_FSTAT_CCIF_MAS; //Start execution
while(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK ==0); //CCIF=1?
}
FTFA->FPROT0=0x00; //Why the line here has a warning?
__enable_irq();
//========================================
//Code for erase an sector 0XFC00 -0xFF:
status_t Flash_Erase(void) //const void *sec)
{
uint8_t TestByte;
TestByte =FTFA->FSTAT;
while(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK ==0); //CCIF =1?
if((TestByte & 0x30)>0)FTFA->FSTAT |=0x30; //write '1' to clear
FTFA->FCCOB0 =Erase1Sector;
FLASH_Addr =FlashStoreStart;
//FTFA->FCCB1 =0x00;
//FTFA->FCCB2 =0xFC;
//FTFA->FCCB3 =0x00;
FTFA->FPROT0=0x80; //highest section 2K byte
FTFA->FPROT1=0x00;
FTFA->FPROT2=0x00;
FTFA->FPROT3=0x00;
FTFA->FSTAT |=FTFA_FSTAT_CCIF_MAS; //Start Erase
while(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK ==0);
FTFA->FCCOB0 =Read1sSection;
FLASH_Addr =FlashStoreStart;
//FTFA->FCCB1 =0x00;
//FTFA->FCCB2 =0xFC;
//FTFA->FCCB3 =0x00;
FTFA->FCCB4 =0x00;
FTFA->FCCB5 =0x01; // 256 longword
FTFA->FCCB6 =0x00; //Norm margin level
FTFA->FSTAT |=FTFA_FSTAT_CCIF_MAS; //Start
while(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK ==0);
if((FTFA->FSTAT & 0x01)!=0)return 1;
else return 0;
}
Best regards,
Albert Zhou
Electronics Engineer
Sensorex Corp.