RX62Nの端子をバウンダリスキャンで操作して、RX62Nに接続されたSDRAMの内容を読み書きすることに成功しました!
RX62Nには、バウンダリスキャンといって、JTAGを通じてI/O端子を操作する機能が備わっています。
この機能を使うと、CPUの動作を止めて、I/O端子を外部から自由に操作することができます。
MITOUJTAG Proを使うとI/O端子の操作方法をC++で簡単に記述することができます。
このようにしてI/O端子を遠隔操作し、CPUにつながっているSDRAMの読み書きができたということです。
そのときの作り出した波形はこんな感じです。

(赤い線は出力、緑の線は入力)
昨日から行った改良で、プログラムをMITOUJTAGから分離し、DLLをリンクするだけよいようにしました。
コンパイルと、実行は次のような感じでとても簡単です。

これが出来て、何が嬉しいかっていうと、RX62Nのプログラムを組まなくても、RX62Nの端子を操作できて、周辺回路を動かせるということなのです。
しかも、RX62Nだけではなく、JTAGに対応しているCPUならば何でもOKなのです。
実際に作ったSDRAM操作プログラムを以下に掲載します。とても簡単でしょ?
// バウンダリスキャンでSDRAMの読み出し
#include "jtagscr.h" // JTAGスクリプト
#include "pindef.h" // ピン定義(ユーザ定義)
#define AJFG_CLI_API extern "C" __declspec(dllimport)
AJFG_CLI_API int AJFGInitialize(const char *pin_file);
unsigned long sd_cmd(int ba,int addr,int ras,int cas,int wen,int cs)
{
SD_A = addr; SD_BA = ba;
SD_RAS = ras; SD_CAS = cas; SD_WEN = wen; SD_CS = cs;
SD_CLK <= "0"; SD_CLK <= "1"; // クロックトグル
return SD_D;
}
int main(int argc,char *argv[])
{
if(AJFGInitialize("sample.pin") < 0) // ピン定義ファイルを指定
{
printf("MITOUJTAGサーバに接続できませんでした\n");
Sleep(1000);
return -1;
}
j_bypass();j_sample();j_extest();
SD_D = "Z"; SD_CKE <= "1"; // 初期設定
sd_cmd(0,0,1,1,1,1); // インアクティブ
sd_cmd(0,0x400,0,1,0,0); // プリチャージ
for(int i=0;i<10;i++) {
sd_cmd(0, 0,1,1,1,0); // NOP
}
sd_cmd(0,0x400,0,1,0,0); // プリチャージ
for(int i=0;i<10;i++) {
sd_cmd(0, 0,1,1,1,0); // NOP
}
// モードレジスタセット
sd_cmd(0, 0x23,0,0,0,0); // CL=2,Burst=8
for(int i=0;i<10;i++) {
sd_cmd(0, 0,1,1,1,0); // NOP
}
sd_cmd(0, 0,0,1,1,0); // ROWアドレスセット
sd_cmd(0, 0,1,1,1,0); // NOP
SD_D <= 0x12345678; sd_cmd(0,0,1,0,0,0); // ライト
SD_D <= 0x11111111; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x22222222; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x33333333; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x13579bdf; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0xdeadbeef; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x98765432; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x31323123; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x2345aaaa; sd_cmd(0,0x408,1,0,0,0); // ライト
SD_D <= 0x30303030; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0xffffffff; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x00000000; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x5a5a5a5a; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0xa5a5a5a5; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x69966996; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= 0x96699669; sd_cmd(0,0,1,1,1,0); // NOP
SD_D <= "Z";
sd_cmd(0, 0,1,1,1,0); // NOP
sd_cmd(0, 0,1,1,1,0); // NOP
sd_cmd(0, 0,1,1,1,0); // NOP
sd_cmd(0, 0,1,1,1,0); // NOP
sd_cmd(0, 0,0,1,1,0); // ROWアドレスセット
sd_cmd(0, 0,1,1,1,0); // NOP
sd_cmd(0, 0,1,0,1,0); // リード
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0,0x408,1,0,1,0)); // リード・プリチャージ
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("%08x ",sd_cmd(0, 0,1,1,1,0)); // NOP
printf("\n");
SD_CKE <= "0";
return 0;
}
最近のコメント