RX62N 周辺機能紹介データフラッシュ データ格納用フラッシュメモリ ルネサスエレクトロニクス株式会社ルネサス半導体トレーニングセンター 2013/08/02 Rev. 1.00 00000-A
コンテンツ データフラッシュの概要 プログラムサンプル 消去方法 書き込み方法 読み出し方法 FCUのリセット プログラムサンプルのカスタマイズ 2
データフラッシュの概要 3
データフラッシュとは フラッシュメモリ フラッシュメモリは消去後に書き込む 消去 書き込みは専用の手続きが必要 用途はデータの格納 1 万回の書き換えサイクルを保証 4
データフラッシュの仕様
データフラッシュのメモリ構成 アドレス 0010 0000h 0010 7FFFh データマット 32K バイト (2K バイト 16 ブロック ) ブロック DB00 DB01 DB02 DB03 DB04 DB05 DB06 DB07 DB08 DB09 DB10 DB11 DB12 DB13 DB14 DB15 6
データフラッシュの動作概要 利用 コピー 書き込み / 消去 7
データフラッシュのフロー 開始 事前準備 消去 書き込み 読み出し 終了 8
データフラッシュのモード リセット フラッシュ P/E モードエントリレジスタ 書き込み 消去不可読み出し可能 書き込み 消去可能データの読み出し不可 9
フラッシュ P/E モードエントリレジスタ (FENTRYR) FEKEY[7:0]=AAh P/E リードモード =00h =80h 10
プログラムサンプル 11
サンプル プログラム仕様 データフラッシュのプログラム例 DB00 ブロックの先頭の 8 バイトにテストデータを書き込みます その後 読み出してベリファイし success または error の判定をします 仕様 周辺クロック 48MHz アドレス データフラッシュメモリ DB00 ブロック 0x0123 テストデータ ( 内蔵 RAM) 0x0123 0010 0000h 0010 07FFh 0x4567 0x89AB 0xCDEF 読み出し書き込みベリファイ 0x4567 0x89AB 0xCDEF success or error 12
プログラム フローチャート リセットスタート main fld_init_fcu_ram FCU RAM へコピー スタートアップルーチン 事前準備 fld_init_pclk_notification 周辺クロック通知 P/E モード? NO YES P/E モードに変更 fld_blank_check_2kb 対象ブロックのブランクチェック ブランク? NO 消去 YES fld_erase_2kb 対象ブロックの消去 書き込み fld_program_8byte 8 バイトの書き込み fld_enable_read 読み出し許可 読み出し SUCCESS ベリファイ? OK ERROR NG 13
データフラッシュを使用するための事前準備 FCU RAM へ FCU ファームウェア格納領域をコピー FCU に周辺クロックの動作周波数を通知 14
FCU RAM へ FCU ファームウェア格納領域をコピーするフロー コピー開始 リードモード? No yes リードモードに変更 FCU RAM へアクセス許可 FCU RAM へコピー コピー終了 15
FCU RAM イネーブルレジスタ (FCURAME) KEY[7:0] = C4h 16
FCU RAM と FCU ファームウェア格納領域の位置 8K バイト コピー 8K バイト 17
main 関数 void main(void) { // 00100000h is top address of DB00 block uint32_t top_addr_db00 = 0x00100000; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db00 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db00 ); // 8byte programming fld_program_8byte( top_addr_db00, test_data ); 事前準備 消去 // set enable to read fld_enable_read(); // verify read = (uint16_t *)top_addr_db00; verify = test_data; for(i=0;i<sizeof(test_data)/sizeof(test_data[0]);i++){ if( *read++!= *verify++ ){ while(fld_error); while(fld_success); main FCU RAM へコピー 周辺クロック通知 P/Eモード? yes 対象ブロックのブランクチェック ブランク? yes 8 バイトの書き込み N o N o P/E モードに変更 対象ブロックの消去 読み出し 書き込み OK SUCCESS 読み出し許可 ベリファイ? ERROR NG 18
FCU RAM へコピーする関数 void fld_init_fcu_ram(void) { int i; static const int fcu_ram_size = 8*1024; // 8K Byte volatile uint32_t *fcu_ram = (uint32_t *)0x007F8000; const volatile uint32_t *fcu_fw = (uint32_t *)0xFEFFE000; // change to read mode if( FLASH.FENTRYR.WORD & 0x00ff ){ FLASH.FENTRYR.WORD = 0xAA00; // AAh is key // to enable an access to the FCU RAM area FLASH.FCURAME.WORD = 0xC401; // C4h is key // copy to FCU RAM form FCU F/W for( i = 0; i < fcu_ram_size/sizeof(uint32_t); i++ ){ *fcu_ram++ = *fcu_fw++; // Copy to FCU RAM form FCU F/W コピー開始リードモード? yes FCU RAMへアクセス許可 FCU RAMへコピー No リードモードに変更 コピー終了 19
FCU に周辺クロックの動作周波数を通知するフロー 通知開始 P/E モード? No yes P/E モードに変更 周辺クロック通知レジスタの設定 周辺クロック通知コマンド発行 コマンド完了待ち 動作周波数の設定 設定した値を通知 エラーチェック 通知終了 20
周辺クロック通知レジスタ (PCKAR) 周辺クロックが 35.9MHz の場合 PCKA[7:0] = 36 21
周辺クロック通知コマンド コードフラッシュ データフラッシュ共通コマンド アドレスは 4 の倍数 RA EA BA WA WDN データフラッシュの任意のアドレスブロックの任意のアドレス書き込み対象の先頭アドレスワードサイズの書き込みデータ 22
フラッシュステータスレジスタ 0(FSTATR0) 23
main 関数 void main(void) { // 00100000h is top address of DB00 block uint32_t top_addr_db00 = 0x00100000; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db00 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db00 ); // 8byte programming fld_program_8byte( top_addr_db00, test_data ); 事前準備 消去 // set enable to read fld_enable_read(); // verify read = (uint16_t *)top_addr_db00; verify = test_data; for(i=0;i<sizeof(test_data)/sizeof(test_data[0]);i++){ if( *read++!= *verify++ ){ while(fld_error); while(fld_success); main FCU RAM へコピー 周辺クロック通知 P/Eモード? yes 対象ブロックのブランクチェック ブランク? yes 8 バイトの書き込み N o N o P/E モードに変更 対象ブロックの消去 読み出し 書き込み OK SUCCESS 読み出し許可 ベリファイ? ERROR NG 24
周辺クロック通知関数 int32_t fld_init_pclk_notification(void) { // 00100000h is top address of DB00 block volatile uint8_t *addr_b = (uint8_t *)0x00100000; volatile uint16_t *addr_w = (uint16_t *)0x00100000; // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // set peripheral clock FLASH.PCKAR.BIT.PCKA = 48; // PCLK = 48 MHz 通知開始 P/E モード? yes No P/E モードに変更 // execute the peripheral clock notification command *addr_b = 0xE9; *addr_b = 0x03; *addr_w = 0x0F0F; *addr_w = 0x0F0F; *addr_w = 0x0F0F; *addr_b = 0xD0; // wait for tpcka time if( wait_frdy( 120 ) == FLD_TMOUT ){ // timeout is 120us reset_fcu(); // error check if( FLASH.FSTATR0.BIT.ILGLERR == 1 ){ return FLD_ERROR; return FLD_OK; 周辺クロック通知レジスタの設定周辺クロック通知コマンド発行コマンド完了待ちエラーチェック通知終了 25
消去方法 26
データフラッシュ消去のフロー 消去開始 P/E モード? yes No P/E モードに変更 ブランクチェック ブランク 書き込み有り 消去 消去終了 27
ブランクチェックのフロー ブランクチェック開始 ブランクチェック許可 チェックサイズの設定 ブランクチェックコマンド発行 コマンド完了待ち エラーチェック チェック結果の受け取り ブランクチェック終了 28
フラッシュモードレジスタ (FMODR) 29
データフラッシュブランクチェック制御レジスタ (DFLBCCNT) 0 0 0 0 0 0 0 1 0 先頭から数えて 1 つ目の 8 バイト領域のブランクチェックを行いたい BCADR[7:0] 00h 01h ブロック 8 バイト 8 バイト FFh 8 バイト 30
ブランクチェックコマンド データフラッシュ専用コマンド RA EA BA WA WDN データフラッシュの任意のアドレスブロックの任意のアドレス書き込み対象の先頭アドレスワードサイズの書き込みデータ 31
データフラッシュブランクチェックステータスレジスタ (DFLBCSTAT) 32
main 関数 void main(void) { // 00100000h is top address of DB00 block uint32_t top_addr_db00 = 0x00100000; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db00 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db00 ); // 8byte programming fld_program_8byte( top_addr_db00, test_data ); 事前準備 消去 // set enable to read fld_enable_read(); // verify read = (uint16_t *)top_addr_db00; verify = test_data; for(i=0;i<sizeof(test_data)/sizeof(test_data[0]);i++){ if( *read++!= *verify++ ){ while(fld_error); while(fld_success); main FCU RAM へコピー 周辺クロック通知 P/Eモード? yes 対象ブロックのブランクチェック ブランク? yes 8 バイトの書き込み N o N o P/E モードに変更 対象ブロックの消去 読み出し 書き込み OK SUCCESS 読み出し許可 ベリファイ? ERROR NG 33
ブランクチェック関数 int32_t fld_blank_check_2kb( uint32_t addr ) { volatile uint8_t *addr_b = (uint8_t *)addr; // use the blank checking command FLASH.FMODR.BIT.FRDMD = 1; // set the blank check size (2 KB) FLASH.DFLBCCNT.BIT.BCSIZE = 1; // execute the Blank checking command *addr_b = 0x71; *addr_b = 0xD0; // wait for tdbc2k time (timeout is 770us) if( wait_frdy( 700*1.1 ) == FLD_TMOUT ){ reset_fcu(); // error check if( FLASH.FSTATR0.BIT.ILGLERR == 1 ){ return FLD_ERROR; // get result of blank checking command if( FLASH.DFLBCSTAT.BIT.BCST == 0 ){ return FLD_BLANK; return FLD_NOBLANK; ブランクチェック開始ブランクチェック許可チェックサイズの設定ブランクチェックコマンド発行コマンド完了待ちエラーチェックチェック結果の受け取りブランクチェック終了 34
消去のフロー 消去開始 消去プロテクトの解除 ブロック単位の消去許可 ブロックイレーズコマンド発行 コマンド完了待ち エラーチェック 消去終了 35
フラッシュライトイレーズプロテクトレジスタ (FWEPROR) 36
データフラッシュ書き込み / 消去許可レジスタ 1(DFLWE1) KEY[7:0] = E1h 37
ブロックイレーズコマンド コードフラッシュ データフラッシュ共通コマンド RA EA BA WA WDN データフラッシュの任意のアドレスブロックの任意のアドレス書き込み対象の先頭アドレスワードサイズの書き込みデータ 38
フラッシュステータスレジスタ 0(FSTATR0) 39
main 関数 void main(void) { // 00100000h is top address of DB00 block uint32_t top_addr_db00 = 0x00100000; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db00 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db00 ); // 8byte programming fld_program_8byte( top_addr_db00, test_data ); 事前準備 消去 // set enable to read fld_enable_read(); // verify read = (uint16_t *)top_addr_db00; verify = test_data; for(i=0;i<sizeof(test_data)/sizeof(test_data[0]);i++){ if( *read++!= *verify++ ){ while(fld_error); while(fld_success); main FCU RAM へコピー 周辺クロック通知 P/Eモード? yes 対象ブロックのブランクチェック ブランク? yes 8 バイトの書き込み N o N o P/E モードに変更 対象ブロックの消去 読み出し 書き込み OK SUCCESS 読み出し許可 ベリファイ? ERROR NG 40
消去関数 int32_t fld_erase_2kb( uint32_t addr ) { volatile uint8_t *addr_b = (uint8_t *)addr; int32_t ret = FLD_OK; // Unprotect FLASH.FWEPROR.BIT.FLWE = 1; // enable to erase all blocks FLASH.DFLWE0.WORD = 0x1EFF; // 1Eh is Key FLASH.DFLWE1.WORD = 0xE1FF; // E1h is Key // execute the block erase command *addr_b = 0x20; *addr_b = 0xD0; // wait for tde2k time (timeout is 275ms) if( wait_frdy( 250*1000*1.1 ) == FLD_TMOUT ){ reset_fcu(); // Error check if( (FLASH.FSTATR0.BIT.ILGLERR == 1) (FLASH.FSTATR0.BIT.ERSERR == 1) ){ ret = FLD_ERROR; //protect and disable to erase FLASH.FWEPROR.BIT.FLWE = 2; FLASH.DFLWE0.WORD = 0x1E00; FLASH.DFLWE1.WORD = 0xE100; return ret; 消去開始消去プロテクトの解除ブロック単位の消去許可ブロックイレーズコマンド発行コマンド完了待ちエラーチェック消去終了 41
書き込み方法 42
データフラッシュ書き込みのフロー 書き込み開始 P/E モード? yes No P/E モードに変更 書き込みプロテクトの解除 ブロック単位の書き込み許可 プログラムコマンド発行 消去プロテクトの解除と共通 ブロック単位の消去許可と共通 コマンド完了待ち エラーチェック 書き込み終了 43
プログラムコマンド データフラッシュ専用コマンド 書き込みワード数 アドレスは 8 の倍数 アドレスは 128 の倍数 <8 バイト書き込み > <128 バイト書き込み > RA EA 0010 0000h 8バイト 0010 0000h 128バイト 0010 0008h 8バイト 0010 0080h 128バイト 0010 0010h 8バイト 0010 0100h 128バイト BA WA WDN データフラッシュの任意のアドレスブロックの任意のアドレス書き込み対象の先頭アドレスワードサイズの書き込みデータ 8 バイト 128 バイト 44
フラッシュステータスレジスタ 0(FSTATR0) 45
main 関数 void main(void) { // 00100000h is top address of DB00 block uint32_t top_addr_db00 = 0x00100000; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db00 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db00 ); // 8byte programming fld_program_8byte( top_addr_db00, test_data ); 事前準備 消去 // set enable to read fld_enable_read(); // verify read = (uint16_t *)top_addr_db00; verify = test_data; for(i=0;i<sizeof(test_data)/sizeof(test_data[0]);i++){ if( *read++!= *verify++ ){ while(fld_error); while(fld_success); main FCU RAM へコピー 周辺クロック通知 P/Eモード? yes 対象ブロックのブランクチェック ブランク? yes 8 バイトの書き込み N o N o P/E モードに変更 対象ブロックの消去 読み出し 書き込み OK SUCCESS 読み出し許可 ベリファイ? ERROR NG 46
書き込み関数 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; // Unprotect and enable to write all blocks FLASH.FWEPROR.BIT.FLWE = 1; FLASH.DFLWE0.WORD = 0x1EFF; // 1Eh is Key FLASH.DFLWE1.WORD = 0xE1FF; // E1h is Key // execute the 8-byte programming command *addr_b = 0xE8; *addr_b = 0x04; for(i=0; i<4; i++){ // 8-byte is 4 word size *addr_w = *ram++; *addr_b = 0xD0; // wait for tdp8 time (timeout is 2.2ms) if( wait_frdy( 2*1000*1.1 ) == FLD_TMOUT ){ reset_fcu(); // error check if( (FLASH.FSTATR0.BIT.ILGLERR == 1) (FLASH.FSTATR0.BIT.PRGERR == 1) ){ ret = FLD_ERROR; //protect and disable to write FLASH.FWEPROR.BIT.FLWE = 2; FLASH.DFLWE0.WORD = 0x1E00; FLASH.DFLWE1.WORD = 0xE100; return ret; 書き込み開始 No P/Eモード? yes P/Eモードに変更書き込みプロテクトの解除 mainで実施ブロック単位の書き込み許可プログラムコマンド発行コマンド完了待ちエラーチェック書き込み終了 47
読み出し方法 48
データフラッシュ読み出しのフロー 読み出し開始 リードモード? No yes リードモードに変更 読み出し許可 読み出し 読み出し終了 49
データフラッシュ読み出し許可レジスタ 0(DFLRE0) KEY[7:0] = 2Dh 50
main 関数 void main(void) { // 00100000h is top address of DB00 block uint32_t top_addr_db00 = 0x00100000; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db00 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db00 ); // 8byte programming fld_program_8byte( top_addr_db00, test_data ); 事前準備 消去 // set enable to read fld_enable_read(); // verify read = (uint16_t *)top_addr_db00; verify = test_data; for(i=0;i<sizeof(test_data)/sizeof(test_data[0]);i++){ if( *read++!= *verify++ ){ while(fld_error); while(fld_success); main FCU RAM へコピー 周辺クロック通知 P/Eモード? yes 対象ブロックのブランクチェック ブランク? yes 8 バイトの書き込み N o N o P/E モードに変更 対象ブロックの消去 読み出し 書き込み OK SUCCESS 読み出し許可 ベリファイ? ERROR NG 51
読み出し許可関数 int32_t fld_enable_read(void) { // change to read mode if( FLASH.FENTRYR.WORD & 0x00ff ){ FLASH.FENTRYR.WORD = 0xAA00; // AAh is key // enable to read all blocks FLASH.DFLRE0.WORD = 0x2DFF; // 2Dh is Key FLASH.DFLRE1.WORD = 0xD2FF; // D2h is Key 読み出し開始 リードモード? yes No リードモードに変更 return FLD_OK; 読み出し許可 読み出し 読み出し終了 main で実施 52
FCU のリセット 53
コマンド完了待ちのタイムアウトと FCU のリセットのフロー コマンド発行 No コマンド完了? タイムアウト? yes yes No エラーチェック FCU のリセット 終了 54
データフラッシュの電気的特性 55
タイムアウト時間 コマンド タイムアウト時間 ブランクチェックコマンド (8バイト) tdbc8 1.1 ブランクチェックコマンド (2Kバイト) tdbc2k 1.1 ブロックイレーズコマンド tde2k 1.1 プログラムコマンド (8バイト書き込み) tdp8 1.1 プログラムコマンド (128バイト書き込み) tdp128 1.1 周辺クロック通知コマンド tpcka tpcka:pclk=50mhz の場合 60μs PCLK=25MHz の場合 120μs 56
コマンド完了待ちをする関数 ( 例 ) 周辺クロックコマンドのコマンド完了待ち int32_t fld_init_pclk_notification(void) { : // wait for tpcka time if( wait_frdy( 120 ) == FLD_TMOUT ){ // timeout is 120us reset_fcu(); : ( 例 ) プログラムコマンドのコマンド完了待ち int32_t fld_program_8byte( uint32_t addr, uint16_t *ram ) { : // wait for tdp8 time (timeout is 2.2ms) if( wait_frdy( 2*1000*1.1 ) == FLD_TMOUT ){ reset_fcu(); : No コマンド完了? タイムアウト? yes yes エラーチェック FCUのリセット No 終了 57
FCU のリセットのフロー FCU のリセット開始 ソフトウェアリセット wait リセット解除 FCU のリセット終了 58
フラッシュリセットレジスタ (FRESETR) FRKEY[7:0] = CCh 59
制御信号タイミングの電気的特性 60
FCU のリセット関数 static void reset_fcu(void) { volatile int32_t w; // FCU reset FLASH.FRESETR.BIT.FRESET = 1; // wait for tresw2 time (tresw2 is 35us) wait_35usec(); // clear FCU reset FLASH.FRESETR.BIT.FRESET = 0; FCUのリセット開始ソフトウェアリセット wait リセット解除 FCU のリセット終了 61
プログラムサンプルのカスタマイズ 62
ブロックの変更 void main(void) { // 00100000h is top address of DB00 block uint32_t top_addr_db00 = 0x00100000; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db00 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db00 ); // 8byte programming fld_program_8byte( top_addr_db00, test_data ); ( 読み出しは省略 ) void main(void) { // 00100800h is top address of DB01 block uint32_t top_addr_db01 = 0x00100800; volatile uint16_t *read; volatile uint16_t *verify; int i; // copy to FCU RAM from FCU F/W fld_init_fcu_ram(); // peripheral clock notification fld_init_pclk_notification(); // change to P/E mode if( (FLASH.FENTRYR.WORD & 0x00ff)!= 0x0080 ){ FLASH.FENTRYR.WORD = 0xAA80; // AAh is key // blank check (2 KB) if( fld_blank_check_2kb( top_addr_db01 )!= FLD_BLANK ){ // block erase fld_erase_2kb( top_addr_db01 ); // 8byte programming fld_program_8byte( top_addr_db01, test_data ); ( 読み出しは省略 ) 63
ブランクチェックサイズの変更 int32_t fld_blank_check_2kb( uint32_t addr ) { volatile uint8_t *addr_b = (uint8_t *)addr; // use the blank checking command FLASH.FMODR.BIT.FRDMD = 1; // set the blank check size (2 KB) FLASH.DFLBCCNT.BIT.BCSIZE = 1; // execute the Blank checking command *addr_b = 0x71; *addr_b = 0xD0; // wait for tdbc2k time (timeout is 770us) if( wait_frdy( 700*1.1 ) == FLD_TMOUT ){ reset_fcu(); // error check if( FLASH.FSTATR0.BIT.ILGLERR == 1 ){ return FLD_ERROR; // get result of blank checking command if( FLASH.DFLBCSTAT.BIT.BCST == 0 ){ return FLD_BLANK; return FLD_NOBLANK; int32_t fld_blank_check_8b( uint32_t addr, uint8_t offset) { volatile uint8_t *addr_b = (uint8_t *)addr; // use the blank checking command FLASH.FMODR.BIT.FRDMD = 1; // set the blank check size (8B) FLASH.DFLBCCNT.BIT.BCSIZE = 0; FLASH.DFLBCCNT.BIT.BCADR = offset; // execute the Blank checking command *addr_b = 0x71; *addr_b = 0xD0; // wait for tdbc8 time (timeout is 33us) if( wait_frdy( 30*1.1 ) == FLD_TMOUT ){ reset_fcu(); // error check if( FLASH.FSTATR0.BIT.ILGLERR == 1 ){ return FLD_ERROR; // get result of blank checking command if( FLASH.DFLBCSTAT.BIT.BCST == 0 ){ return FLD_BLANK; return FLD_NOBLANK; 64
書き込みサイズの変更 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; // Unprotect and enable to write all blocks FLASH.FWEPROR.BIT.FLWE = 1; FLASH.DFLWE0.WORD = 0x1EFF; // 1Eh is Key FLASH.DFLWE1.WORD = 0xE1FF; // E1h is Key // execute the 8-byte programming command *addr_b = 0xE8; *addr_b = 0x04; for(i=0; i<4; i++){ // 8-byte is 4 word size *addr_w = *ram++; *addr_b = 0xD0; // wait for tdp8 time (timeout is 2.2ms) if( wait_frdy( 2*1000*1.1 ) == FLD_TMOUT ){ reset_fcu(); // error check if( (FLASH.FSTATR0.BIT.ILGLERR == 1) (FLASH.FSTATR0.BIT.PRGERR == 1) ){ ret = FLD_ERROR; //protect and disable to write FLASH.FWEPROR.BIT.FLWE = 2; FLASH.DFLWE0.WORD = 0x1E00; FLASH.DFLWE1.WORD = 0xE100; return ret; int32_t fld_program_128byte( 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; // Unprotect and enable to write all blocks FLASH.FWEPROR.BIT.FLWE = 1; FLASH.DFLWE0.WORD = 0x1EFF; // 1Eh is Key FLASH.DFLWE1.WORD = 0xE1FF; // E1h is Key // execute the 8-byte programming command *addr_b = 0xE8; *addr_b = 0x40; for(i=0; i<64; i++){ //128-byte is 64 word size *addr_w = *ram++; *addr_b = 0xD0; // wait for tdp128 time (timeout is 5.5ms) if( wait_frdy( 5*1000*1.1 ) == FLD_TMOUT ){ reset_fcu(); // error check if( (FLASH.FSTATR0.BIT.ILGLERR == 1) (FLASH.FSTATR0.BIT.PRGERR == 1) ){ ret = FLD_ERROR; //protect and disable to write FLASH.FWEPROR.BIT.FLWE = 2; FLASH.DFLWE0.WORD = 0x1E00; FLASH.DFLWE1.WORD = 0xE100; return ret; 65
END ルネサスエレクトロニクス株式会社