UMEHOSHI ITA TOP PAGE    COMPUTER SHIEN LAB

UMEHOSHI IT (my_util.c と my_util.h)

my_util.hのソース

#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 */

my_util.cのソース

#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();
        }*/
}