/************************(abc899-18325.c)*******************
* I2C接続EEPROM(24FC1025)読み書きテスト
***********************************************************/
#define DEVICE 0x50 // Blk0=0x50,Blk1=0x54
#define MBFSIZE 78 // メモリ操作用バッファーサイズ
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#include "i2cLCD_ST7032i.h"
#include "ctype.h" // isxdigit()
#include "stdio.h" // puts(),..
#include "stdlib.h" // atoi()...
#include "string.h" // strtok()...
//#include
//=== グローバル変数 ============
char Dlm[] = ","; // 文字列区切りデリミタ
//--- シリアル通信用
char RBuf[BFSIZE]; // シリアル受信用
// BFSIZEはeusart.hで宣言
uint8_t SFlg; // シリアル受信フラグ
char SBuf[20]; // 文字列処理用バッファー
//--- I2Cメモリー用
uint8_t BlkNum = 0; // メモリブロック番号
uint16_t CrtAdr = 0; // カレントアドレス
uint8_t DBuf[MBFSIZE]; // ページメモリ用バッファー
uint8_t SqMode; // シーケンスモードフラグ
/*************************************
* I2C EEPROM function
**************************************/
//----- アドレスadrから、1バイトを読み出す
uint8_t I2C_Mem_Read(uint16_t adr){
uint8_t bf[2];
bf[0] = adr >> 8;
bf[1] = (uint8_t)adr;
I2C1_WriteNBytes(DEVICE + BlkNum,bf,2);
I2C1_ReadNBytes(DEVICE + BlkNum,bf,1);
return bf[0];
}
//----- アドレスadrに、1バイトdtを書き込む
void I2C_Mem_Write(uint16_t adr, uint8_t dt){
uint8_t bf[3];
bf[0] = adr >> 8;
bf[1] = (uint8_t)adr; // アドレスセット
bf[2] = dt; // データセット
I2C1_WriteNBytes(DEVICE + BlkNum,bf,3); //書き込む
__delay_ms(5);
}
//----- アドレスadrからnバイトをary[]に読み出す
void I2C_Mem_NRead(uint16_t adr, uint8_t *ary, uint8_t n){
uint8_t bf[2];
bf[0] = adr >> 8;
bf[1] = (uint8_t) adr;
if(n > MBFSIZE) n = MBFSIZE; // 配列要素数以内
I2C1_WriteNBytes(DEVICE+BlkNum,bf,2); // アドレス送信
I2C1_ReadNBytes(DEVICE+BlkNum,ary,n); // データ読込
}
//----- アドレスadrからary[]のnバイトを書き込む
void I2C_Mem_NWrite(uint16_t adr, uint8_t *ary, uint8_t n){
uint8_t bf[MBFSIZE + 2];
bf[0] = adr >> 8; // アドレスセット
bf[1] = (uint8_t) adr; // ページ境界に注意!
if(n > MBFSIZE) n = MBFSIZE;
memcpy(bf+2,ary,n); // ary[]をbf[]にコピー
I2C1_WriteNBytes(DEVICE+BlkNum,bf,n+2);
__delay_ms(5);
}
//---- ターミナルにプロンプト文字表示
void prtPrompt(uint8_t m){
if(m) printf("# "); // 連続書込モード中
else printf("$ "); // 通常書込モード
}
//---- 16進文字列を10進数に変換
int16_t my_xtoi(char *str){
uint32_t dec;
dec = strtoul(str,NULL,16);
if(errno == ERANGE) return -1; // 文字列変換エラー
return (int16_t)dec;
}
/************************************
* コマンドアクション
************************************/
//----- Wコマンド W[aaaa][,[d0,・・[,]]]
uint16_t cmd_W(char *str){
char *pt; // 文字列操作用ポインタ
uint8_t last; // 文字列の最後の位置
int16_t res = 0; // Hex文字数値変換結果
uint8_t dt = 0; // 書き込むバイトデータ
uint16_t cnt = 0; // 実際に書き込んだバイト数
if(strlen(str)==1){ // 'W'のみなら
SqMode = 1; // 連続書込モードにセット
puts("SqMode ON\n\r");
return 0; // データは書き込まない
}
last = (uint8_t)strlen(str)-1; // 文字列の行末位置を取得
if(str[last] == ','){ // 行末がコンマなら
SqMode = 1; // 連続書込モードにセット
puts("SqMode ON\n\r");
str[last]='\0'; // 行末のコンマを消す
}
if(str[1]!=','){ // 第2文字がコンマか?
pt = strtok(str+1,Dlm); // コマンドの次文字から
if(pt != NULL){ // アドレスデータがある
res = my_xtoi(pt);
if(res < 0) return cnt; // 文字変換エラー
CrtAdr = (uint16_t)res;
}
pt = strtok(NULL,Dlm); // 次文字列取込
}else{
pt= strtok(str+1,Dlm); // 文字列取込
}
do{
if(pt != NULL){ // データがあるか?
res = my_xtoi(pt);
if(res < 0) return cnt;
dt = (uint8_t)res;
I2C_Mem_Write(CrtAdr,dt); // データを書き込む
sprintf(SBuf,"%d:%04X < %02X",BlkNum,CrtAdr,dt);
printf("%s\n\r",SBuf);
LCD_cursor(1,1); LCD_str(SBuf);
CrtAdr++; cnt++;
pt = strtok(NULL,Dlm); // 次文字へ
}
}while(pt != NULL); // データがあるだけ繰り返す
return cnt; // 書き込んだ文字数を返す
}
//---- Rコマンド R[aaaa][,n]
uint16_t cmd_R(char *str){
char *pt; // 文字列操作用ポインタ
uint16_t n = 1; // 指定された読込バイト数
int16_t res = 0; // Hex文字数値変換結果
uint8_t dt; // 読み込んだバイトデータ
uint16_t cnt = 0; // 実際に読み出されたバイト数
uint8_t i; // ループ変数
if(strlen(str) > 1){
if(str[1]==','){
pt = strtok(str+2,Dlm);
if(pt != NULL){ // データ無し?
res = my_xtoi(pt);
if(res < 0) return cnt;
n = (uint16_t)res;
}
}else{
pt = strtok(str+1,Dlm);
if(pt != NULL){ // addressがある?
res = my_xtoi(pt);
if(res < 0) return cnt; // 文字列変換エラー
CrtAdr = (uint16_t)res;
}
pt = strtok(NULL,Dlm); // 次文字へ
if(pt != NULL){ // データ無し?
res = my_xtoi(pt);
if(res < 0) return cnt;
n = (uint16_t)res;
}
}
}
for(i = 0; i < n;i++ ){
dt = I2C_Mem_Read(CrtAdr); // データを読み出す
sprintf(SBuf,"%d:%04X > %02X",BlkNum,CrtAdr,dt);
printf("%s\n\r",SBuf);
LCD_cursor(1,1); LCD_str(SBuf);
CrtAdr++; cnt++;
}
SqMode = 0;
// puts("SqMode OFF");
return cnt; // 読み込んだデータ数を返す
}
//---- WSQ (連続書込モード)
uint16_t cmd_WSQ(char *str){
char *pt; // 文字列操作用ポインタ
uint8_t dt; // 書き込むバイトデータ
int16_t res; // Hex文字数値変換結果
uint16_t cnt = 0; // 実際に読み出されたバイト数
pt = strtok(str,Dlm);
while(pt != NULL){ // データがあるだけ繰り返す
res = my_xtoi(pt);
if(res < 0) return cnt; // 文字列変換エラー
dt = (uint8_t)res;
I2C_Mem_Write(CrtAdr,dt); // データを書き込む
printf("%d:%04X < %02X\n\r",BlkNum,CrtAdr,dt);
CrtAdr++; cnt++;
pt = strtok(NULL,Dlm); // 次文字列へ
}
return cnt; // 書き込んだデータ数を返す
}
//---- MBコマンド MBn
int cmd_M(char *str){
char *pt; // 文字列操作用ポインタ
uint8_t b; // メモリバンク番号
if(str[1] != 'B') return -1; // 第2文字がBか?
pt = strtok(str+2,Dlm);
if(pt==NULL) return -1; // 文字列変換エラー
b = atoi(pt) & 0x01;
printf("Bank %d selected\n\r",b);
BlkNum = b * 4; // Blk = bit2
CrtAdr = 0; // 現在アドレスは0に
SqMode = 0;
// puts("SqMode OFF\r");
return b;
}
//---- Qコマンド(連続書込モードの解除) Q
void cmd_Q(char *str){
SqMode = 0;
puts("SqMode OFF\r");
}
//---- U(dump)コマンド U[aaaa]
// (64バイトのデータをDBuf[]に読み出す)
int cmd_U(char *str){
char *pt; // 文字列操作用ポインタ
int16_t res; // Hex文字数値変換結果
uint16_t ad; // 指定アドレス
uint8_t i; // ループ処理用
pt = strtok(str+1,Dlm);
if(pt != NULL){ // アドレス有り?
res = my_xtoi(pt);
if(res < 0) return -1; // 文字列変換エラー
CrtAdr = (uint16_t)res;
}
ad = CrtAdr & 0xFFC0; // 64バイト単位に
I2C_Mem_NRead(ad,DBuf,64); // 64バイトをDBuf[]に読出し
printf("%d:%04X - %04X",BlkNum,ad,ad+63);
for(i = 0; i < 64; i++){ // 16x4文字表示
if(i % 16 == 0) printf("\n\r");
printf(" %02X",DBuf[i]);
}
puts("\r");
SqMode = 0;
return 0;
}
//---- P(Page)コマンド PW[aaaa]
// (DBuf[]の64バイトをメモリに書き込む)
int cmd_P(char *str){
char *pt; // 文字列操作用ポインタ
int16_t res; // Hex文字数値変換結果
uint16_t ad; // 指定アドレス
uint8_t i; // ループ処理用
if(str[1] != 'W') return -1; // 第2文字がW?
pt = strtok(str+2,Dlm);
if(pt != NULL){ // アドレス有り?
res = my_xtoi(pt);
if(res < 0) return -1; // 文字列変換エラー
CrtAdr = (uint16_t)res;
}
ad = CrtAdr & 0xFFC0; // 64バイト単位に
I2C_Mem_NWrite(ad,DBuf,64); // DBuf[]の64バイト書込
printf("Page Write %d:%04X - %04X\n\r",BlkNum,ad,ad+63);
SqMode = 0;
return 0;
}
/********************************
* main apprication
********************************/
void main(){
char cmd; // コマンド文字
SYSTEM_Initialize();
LCD_init(); // LCD初期化
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
puts("ready\r");
LCD_str("ready"); // コマンド処理準備完了
prtPrompt(SqMode);
while(1){
if(SFlg){ // シリアル入力有り?
LCD_clr(); LCD_str(RBuf); // LCDにコマンド表示
cmd = RBuf[0]; // コマンドは第1文字
printf("\n\r");
switch(cmd) { // 各コマンドの実行
case 'W': cmd_W(RBuf); break;
case 'R': cmd_R(RBuf); break;
case 'Q': cmd_Q(RBuf); break;
case 'M': cmd_M(RBuf); break;
case 'U': cmd_U(RBuf); break;
case 'P': cmd_P(RBuf); break;
// 有効なコマンドがなく
default: if(SqMode) cmd_WSQ(RBuf);
// 連続書込モード中なら
break; // 書込シーケンスを実行
}
SFlg = 0;
prtPrompt(SqMode);
}
}
}
|