UMEHOSHI ITA TOP PAGE COMPUTER SHIEN LAB
#ifndef _MY_UTIL_H /* Guard against multiple inclusion */ #define _MY_UTIL_H // 【2023-4】でファイルを追加 // EEPROM 制御関数 unsigned int NVM_unlock (unsigned int nvmop);//ロック解除,NVMCON設定シーケンス unsigned int NVM_erase_page(unsigned int address);// address指定で1ページ(1024バイト)を0xffに消去 unsigned int NVM_write_word (unsigned int address, unsigned int data);//addressの位置にdataワードを書き込む int get_version(); // バージョンを返す。 void power_on_start(); #endif /* _MY_UTIL_H */
#include <xc.h> #include <proc/p32mx270f256b.h> #include <stdlib.h> #include "my_util.h" #include "common.h" // 参考: 60001121G_JP.pdf の不揮発性メモリ ( NonVolatile Memory )CONTROL unsigned int NVM_unlock (unsigned int nvmop)//ロック解除,NVMCON 設定シーケンス { unsigned int status; asm volatile ("di %0" : "=r" (status));// Disable all Interrupts NVMCON = nvmop; // NVM(SFR)Flashプログラミング制御レジスタ設定 NVMKEY = 0xAA996655;//EEPROMの意図しない書き込みなどを防ぐ指定シーケンス1 NVMKEY = 0x556699AA;//EEPROMの意図しない書き込みなどを防ぐ指定シーケンス2 NVMCONSET = 0x8000;// Start the operation using the Set Register while (NVMCONbits.WR){ ;// Wait for operation to complete } if (status & 0x00000001){ asm volatile ("ei");// Restore Interrupts } else { asm volatile ("di"); } NVMCONCLR = 0x0004000; // Disable NVM write enable return (NVMCON & 0x3000);// Return WRERR and LVDERR Error Status Bits // bit13:WRERRのbitが1の時、プログラミングまたは消去シーケンスは正常に完了しなかった // bit12:LVDERRのbitが1の時、WRERRがセットされた場合、データは破損した可能性がある } // UMEHOSHI_ITAで使っているのはPIC32MX270F256Bでプログラムフラシュの // kseg0_program_memは、0x9D000000より0x9D03F000の範囲 // 0x9D020000?をこの引数にして消去可能(ページ消去で消せるのは1024バイト) // 0x9D03F000-0x9D020000=126976が一般ユーザが書き込める範囲となる // 次の消去アドレスは0x9D020200、次が0x9D020400で、0x9d03ee00まで指定可 unsigned int NVM_erase_page(unsigned int address) { unsigned int res; if( address < 0xB0000000U) address += +0x20000000U; NVMADDR = (unsigned int) address; // 書き込みアドレス(書き込み位置) // 書き込みモードの指定 // 0001 - 4バイト単位で書き込む // 0011 - 512バイト単位で書き込む(指定アドレスは512の倍数) // 0100 - 512バイト消去ページ消去動作: NVMADDRで選択したページを消去する // 0101 - プログラム領域をすべて消去(ブート領域でのみ実行可) //NVMCONbits.NVMOP = 0b0001; // WordWrite //NVMCONbits.WREN = 1;// 書き込みの許可(bit 14 WREN: 書き込みイネーブルビット) //0x4001;// NVM(SFR)Flashプログラミング制御レジスタ設定 res = NVM_unlock (0x4000);//WRERR: 書き込みエラービットをクリア res |= NVM_unlock (0x4004);// メモリ初期化のページ消去動作 return res;// Return Result(ゼロが戻れば成功) } // PIC32MX270F256Bでプログラムフラシュの kseg0_program_memは、0x9D000000より // 0x9D03F000の範囲で、dataの1ワード(32bit)を、addressの位置に書き込む。 unsigned int NVM_write_word (unsigned int address, unsigned int data) { unsigned int res; NVMDATA = data; // 書き込みデータ asm("nop"); if( address < 0xB0000000U) address += +0x20000000U; NVMADDR = address; // 書き込みアドレス(書き込み位置) // 書き込みモードの指定 // 0001 - 4バイト単位で書き込む // 0011 - 512バイト単位で書き込む(指定アドレスは512の倍数) // 0100 - 4KB単位で消去 // 0101 - プログラム領域をすべて消去(ブート領域でのみ実行可) //NVMCONbits.NVMOP = 0b0001; // WordWrite //NVMCONbits.WREN = 1;// 書き込みの許可(bit 14 WREN: 書き込みイネーブルビット) //0x4001;// NVM(SFR)Flashプログラミング制御レジスタ設定 res = NVM_unlock (0x4001); return res;// Return Result } int get_version(){//バージョンを返す return 1; // 2023-4 } void power_on_start(){ if ((PORTB & 0x80) == 0) return; // SW2が押されてれば、リターン // SW2が押されていない場合の起動 unsigned *flag = (unsigned *) 0x9D03fff0; if( *flag == 0xffffffff) return; void (* func)(void) = (void *) *flag; func(); /* void (* func)(void) = (void *) 0x9D020000; // 上記に変更 202307 if( *((uint32_t *)func) != 0xffffffff ){// EEPROMの記憶内容が0xffでない? func(); }*/ }