XC3S50-4VQ100Cのconfigを自分でやる件です.(config ROMを使わずに)
前回は.binの作り方を説明しました.
作業手順的に、次にやるのはSerial FLASH W25Q32に.binを焼く作業です.HDD上の.binをFLASHの先頭からそのまま書きます.
↓現物はこんなです.FLASHはarduinoの下に隠れています.
↓回路図(pdf) Arduino nanoとW25Q32の部分だけです.上の現物写真の右側の基板.to FPGAの先にFPGA基板を取り付けます.FPGAの回路図は次回公開します.
・ArduinoのUSB(COM port)でPCへ接続する
・PCはterminal softのTeraTermをつかう
・TeraTermに.binをbinary送信させる
・Arduinoは受信した.binを256bytes貯まった都度W25Q32にpage writeする
・ArduinoはFLASHを消去したり、FLASHをdumpする機能も持つ
もう少し細かいこと.受信bufferについて.
・256byteの受信bufferを2本用意して交互に切り替えて使う
・COM portて届いたdataを受信bufferに積み積みする
・256byte貯まったらFLASHへpage writeする
・FLASHの256byte page writeに要する時間は2mSec(実測)
・PCとCOM portの接続速度は9600bpsにする
・9600bpsで256byte受信するには250mSecぐらいかかる
・250mSec >> 2mSec なのでFLASH page writeが邪魔されない
Arduino sourceを置きます(zip)
FLASHを焼く操作はこうします.
1)TeraTermで「e」と打つ =FLASH全域消去
2)TeraTermで「f」と打つ =.binをFLASHに焼く
3)20秒以内に.binをバイナリ送信する
4)2分ぐらい待つと終わる
ーーーー
以下はsourceの簡単な説明.
PCコマンドの処理は、いつものloop関数からPCcommand()を読んでます.
void loop() {
PCcommand();
}
PCcommand()の中で各種コマンド分岐します.fの場合は、、、
switch(c[0]){
case 'f': // flash write
Serial.print("flash write mode. .........bin in 20Sec\n");
mode='f';
bufsel = 0; 2本のbufferの切り替え
fileptr = 0; .binの先頭からのbyte counter
TIM2cnt_filetrans_start_timeout=20; // 20Sec timer
break;
flashWrite()で.bin受信とFLASH焼きをやります.
やってることは、256byte溜まったらbuffer切り替えしてFLASHに焼きます.
.bin file末尾では半端なサイズがbufferに残ります.
そこで受信が停まって10秒待ってtimeoutしたら、残をFLASH焼きします.
詳しくはsourceを見てちょ.
ーーーー
次の話題はFLASH W25Q32のコマンドについて.
大雑把にこの3種類の形式です.
コマンド 例:全域消去
コマンド+データ 例:status read
コマンド+アドレス+データ 例:read/write
よく使うコマンドは、、、
#define WR_EN 6
#define CHIP_ERASE 0xC7
#define PAGE_PROG 2
#define RD_DATA 3
page writeはこんな風にします.
WEN→CS→write command→A[23:0]→data[7:0]→xCS→wait busy
void W25Q_writePage(long adrs, byte *data, int length){
W25Q_command(WR_EN,0); // write enable command
digitalWrite(slaveSelectPin, LOW);
SPI.transfer(PAGE_PROG); // page write command
SPI.transfer(adrs>>16);
SPI.transfer(adrs>>8);
SPI.transfer(adrs);
byte *d;
d = data;
for(int i=0; i<length; i++) SPI.transfer(*d++);
digitalWrite(slaveSelectPin, HIGH);
W25Q_waitBusy(); // loop during busy
}
全域消去はこんなです.
WEN→CS→erase command→xCS→wait busy
void W25Q_eraseChip(void){
W25Q_command(WR_EN,0); // write enable
digitalWrite(slaveSelectPin, LOW);
SPI.transfer(CHIP_ERASE);
digitalWrite(slaveSelectPin, HIGH);
W25Q_waitBusy(); // loop during busy
}
詳しくはsourceを見てちょ.
説明ってこんなところかな.今朝はここまでにしとうございます.
かしこ
0 件のコメント:
コメントを投稿