RX220のE2データフラッシュを使用するためのコードを書いたので公開します。といってもルネサス公式のサンプルプログラムそのままですが。これにより電源を落としてもE2データフラッシュに書き込んだデータなら保持することができるようになります。
自分の環境ではRXにプログラムを書き込むとROM内が消去されるみたいです。
ROMに書き込みや消去を行うにはそれなりに時間がかかるのでdelay関数をつくる必要があります。
18/3/16追記 E2ROM.cに一部バグがありました。修正済みです。
https://elearning.renesas.com/pluginfile.php/355/mod_folder/content/0/RX_MCU_Japanese/RX62N_FLD.pdf?forcedownload=1
E2ROM.h
#ifndef E2ROM_H_
#define E2ROM_H_
#include "iodefine.h"
#include "stdint.h"
enum status {FLD_ERROR,FLD_OK,FLD_TMOUT,FLD_BLANK,FLD_NOBLANK};
int wait_FRDY(unsigned int wait);
static void reset_fcu(void);
int32_t fld_init_pclk_notification(void);
int32_t fld_blank_check_2KB( uint32_t addr );
int32_t fld_erase_2KB( uint32_t addr );
int32_t fld_program_2byte( uint32_t addr, uint16_t *ram );
int32_t fld_program_8byte( uint32_t addr, uint16_t *ram );
int32_t fld_enable_read(void);
int32_t fld_enable_PE(void);
#endif
E2ROM.c
#include "E2ROM.h"
int32_t fld_init_pclk_notification(void)
{
volatile uint8_t *addr_b = (uint8_t *)0x00100000;
volatile uint16_t *addr_w = (uint16_t *)0x00100000;
if( (FLASH.FENTRYR.WORD & 0x00ff) != 0x0080 ){
FLASH.FENTRYR.WORD = 0xAA80;
}
FLASH.PCKAR.BIT.PCKA = 32;
*addr_b = 0xE9;
*addr_b = 0x03;
*addr_w = 0x0F0F;
*addr_w = 0x0F0F;
*addr_w = 0x0F0F;
*addr_b = 0xD0;
if( wait_FRDY( 120 ) == FLD_TMOUT ){
reset_fcu();
}
if( FLASH.FSTATR0.BIT.ILGLERR == 1 ){
return FLD_ERROR;
}
return FLD_OK;
}
int32_t fld_blank_check_2KB( uint32_t addr )
{
volatile uint8_t *addr_b = (uint8_t *)addr;
FLASH.FMODR.BIT.FRDMD = 1;
FLASH.DFLBCCNT.BIT.BCSIZE = 1;
*addr_b = 0x71;
*addr_b = 0xD0;
if( wait_FRDY( 700*1.1 ) == FLD_TMOUT ){
reset_fcu();
}
if( FLASH.FSTATR0.BIT.ILGLERR == 1 ){
return FLD_ERROR;
}
if( FLASH.DFLBCSTAT.BIT.BCST == 0 ){
return FLD_BLANK;
}
return FLD_NOBLANK;
}
int32_t fld_erase_2KB( uint32_t addr )
{
volatile uint8_t *addr_b;
int32_t ret = FLD_OK;
int i=0;
FLASH.FWEPROR.BIT.FLWE = 1;
FLASH.DFLWE0.WORD = 0x1E0F;
for(i=0;i<16;i++){
addr_b = (uint8_t *)((uint32_t)addr + (uint32_t)128*i);
*addr_b = 0x20;
*addr_b = 0xD0;
if( wait_FRDY( 250*1000*1.1 ) == FLD_TMOUT ){
reset_fcu();
}
if( (FLASH.FSTATR0.BIT.ILGLERR == 1) || (FLASH.FSTATR0.BIT.ERSERR == 1) ){
ret = FLD_ERROR;
}
}
FLASH.FWEPROR.BIT.FLWE = 2;
FLASH.DFLWE0.WORD = 0x1E00;
return ret;
}
int32_t fld_program_2byte( uint32_t addr, uint16_t *ram )
{
volatile uint8_t *addr_b = (uint8_t *)addr;
volatile uint16_t *addr_w = (uint16_t *)addr;
int32_t ret = FLD_OK;
FLASH.FWEPROR.BIT.FLWE = 1;
FLASH.DFLWE0.WORD = 0x1EFF;
*addr_b = 0xE8;
*addr_b = 0x01;
*addr_w = *ram;
*addr_b = 0xD0;
if( wait_FRDY( 2*1000*1.1 ) == FLD_TMOUT ){
reset_fcu();
}
if( (FLASH.FSTATR0.BIT.ILGLERR == 1) || (FLASH.FSTATR0.BIT.PRGERR == 1) ){
ret = FLD_ERROR;
}
FLASH.FWEPROR.BIT.FLWE = 2;
FLASH.DFLWE0.WORD = 0x1E00;
return ret;
}
int32_t fld_program_8byte( uint32_t addr, uint16_t *ram )
{
volatile uint8_t *addr_b = (uint8_t *)addr;
volatile uint16_t *addr_w = (uint16_t *)addr;
int32_t i,ret = FLD_OK;
FLASH.FWEPROR.BIT.FLWE = 1;
FLASH.DFLWE0.WORD = 0x1EFF;
*addr_b = 0xE8;
*addr_b = 0x04;
for(i=0; i<4; i++){
*addr_w = *ram++;
}
*addr_b = 0xD0;
if( wait_FRDY( 2*1000*1.1 ) == FLD_TMOUT ){
reset_fcu();
}
if( (FLASH.FSTATR0.BIT.ILGLERR == 1) || (FLASH.FSTATR0.BIT.PRGERR == 1) ){
ret = FLD_ERROR;
}
FLASH.FWEPROR.BIT.FLWE = 2;
FLASH.DFLWE0.WORD = 0x1E00;
return ret;
}
int32_t fld_enable_read(void)
{
if( FLASH.FENTRYR.WORD & 0x00ff ){
FLASH.FENTRYR.WORD = 0xAA00;
}
FLASH.DFLRE0.WORD = 0x2DFF;
return FLD_OK;
}
int32_t fld_enable_PE(void)
{
if( (FLASH.FENTRYR.WORD & 0x00ff) != 0x0080 ){
FLASH.FENTRYR.WORD = 0xAA80;
}
FLASH.DFLRE0.WORD = 0x2D00;
return FLD_OK;
}
int wait_FRDY(unsigned int wait){
unsigned int cnt=0;
while(FLASH.FSTATR0.BIT.FRDY==0){
delay_us(1);
cnt++;
if(cnt==wait) return FLD_TMOUT;
}
return FLD_OK;
}
static void reset_fcu(void)
{
volatile int32_t w;
FLASH.FRESETR.BIT.FRESET = 1;
delay_us(35);
FLASH.FRESETR.BIT.FRESET = 0;
}
使用例
E2データフラッシュ領域の先頭へ0xFFFFを書き込み、その後読み出す。
uint32_t top_addr_db00 = 0x00100000;
volatile uint16_t *read;
unsigned short int test =0xFFFF;
unsigned short int *test_data=&test;
fld_init_pclk_notification();
fld_enable_PE();
if( fld_blank_check_2KB( top_addr_db00 ) !=FLD_BLANK ){
fld_erase_2KB( top_addr_db00 );
}
fld_program_2byte( top_addr_db00, test_data );
fld_enable_read();
read = (uint16_t *)top_addr_db00;