LCD穴を切削し直しました。まぁ見れなくもないくらいに。製品のようにパリっと
仕上げたいのだけど、今の僕ではこのあたりが限界だ。うねりがひどい。

昨日はなんとなく動かした拡張RAM上での実行、きちんとやり直した。ルネサスの モニタで初期化するルーチン(C版)は

昨日はなんとなく動かした拡張RAM上での実行、きちんとやり直した。ルネサスの モニタで初期化するルーチン(C版)は
void
bsc_init ()
{
// MCU Mode 5
このボードはMCUモード5、1MBのアドレス空間で動作させることを前提としています。
// Bus width.
*BSC_ABWCR = 0xff; // All 8bit. D15-D8. D0-D7 are I/O Port (4)
バス幅の設定。エリア0-7まで全て8bit。内蔵RAM,ROM,デバイスは、この設定に
よらないので、RAM,ROMは16bit,2ステートでアクセスされる。内蔵デバイスは
3ステート。拡張したSRAM とLCDが8bitアクセスになる。一つのエリアでも
16bitになるとD0-D7はI/Oポートとして使えなくなる。この場合D0-D7はI/Oポー
ト4として使える。
25MHzで動かしているので1ステートは40ns。
// Access state.
*BSC_ASTCR = 0x70;// CS4,5(Ext.RAM) and CS6 LCD are 3 state access.
拡張したSRAM、LCDは3ステートに。3ステートアクセスの場合、さらにWSC(Wait
State Controler)で追加の待ちのステートを(3まで)入れることができる。
// WSC programmable wait mode. 3 wait state.
*BSC_WCR = 3;
WSCを有効にして、追加ステートは3。これは固定なので、エリアごとに追加ス
テートを変更することはできない。WCERでWSCを有効にするか、切るかの二択。
外部端子からのWAIT#は使わない。外部端子を使う(WMS1=1)とした時はポート6
の設定に注意。
// CS6(LCD) uses WSC. Ext.RAM don't use wait state.
*BSC_WCER = 0x40;
拡張RAMは3ステートアクセス。LCDは3ステートアクセスで、さらにウェイトで
3ステートに設定(計6ステート)。WCERのいずれかが0になってしまうので、ポー
ト6の設定に注意。この場合WAIT#を使わなくてもP6-0はWAIT#端子になってしま
う。
LCDとSRAMでウェイトを変更したいのでしかたがない。SRAMが2ステートで動け
ば、2ステートの場合はウェイトを入れることがないのでWCERを0xffとして
WAIT#を空けることができるのだけど...。
// Bus release disable. BACK#, BREQ# -> Port 6[1:2]
*BSC_BRCR = 0;
外部にバス権を明け渡すことはないのでBRLEは0。モード5なのでA21E, A22E,
A23Eは関係ない。これでBACK#, BREQ#端子が空くのでポート6-1,6-2が使える。
これはボード内蔵のLEDの二個につながっている。
// Enable Chip Select output 4-6
*BSC_CSCR = 0x70;
拡張SRAM、LCD用のチップセレクト信号を出すように設定。これによって
PA-4,5,6が供出される。このレジスタによってチップセレクト信号を出力する
ように設定した場合、この設定が全てに優先されるのでPAのDDRはどう設定して
も問題ない。
// Set address line (A0-A17) output.
P1->DDR = 0xff;
P2->DDR = 0xff;
P5->DDR = 0x01; //use A16 only. A17-A19 are I/O port. (3 Push buttons)
P5はアドレスラインの一部をI/Oポートに供出。これは拡張RAM上でプログラム
を実行する場合、二度と変更できない。P5[1:3]はボード内蔵のプッシュボタン
につながっている。
// AS#, RD#, HWR#, LWR#, WAIT# Don't use external bus.
P6->DDR = 0x6; // BACK#, BREQ# are I/O port. (LED Output)
BACK#, BREQ#を使わないことにしたので、P6-1,2はI/Oポートに使える。
WSCの設定によって#WAITのP6-0はI/Oポートとして使えない。P6-3:6は
モード5に設定した場合はAS#, RD#, HWR#, LWR#固定でDDRの設定は効かない。
}
これでロムモニタ側はOK(のはず)。ユーザプログラム側に移って、まずはスタックの設定、スタックは内蔵RAMにとります。
.h8300h .section .vectors .long start .section .text .globl start start: mov.l #stack_top, er7 loop: jmp @_machine_startup jmp @loop /* NOTREACHED */
void
machine_startup ()
{
extern char bss_start[], bss_end[];
char *p;
bool ram_ok;
// Check BSS
ram_ok = check_ram ((uint32_t)bss_start, (uint32_t)bss_end, FALSE);
.bss領域のSRAMのチェック。この段階では.dataと.stackしか使えないのに注意。
// Clear BSS
for (p = bss_start; p < bss_end; p++)
*p = 0;
ここから普通に動く。
// Initialize H8 devices
sci_init (1);
ここからprintfが使える
SCI_PRINTF ("bss: 0x%x-0x%x\n", (uint32_t)bss_start, (uint32_t)bss_end);
if (!ram_ok)
SCI_PRINTF ("bss RAM error.\n");
// MCU mode. (5)
SCI_PRINTF ("MCU mode: %x\n", *MDCR & 0x3);
if ((*MDCR & 0x3) != 1)
SCI_PRINTF ("Mode error.\n");
// Check RAM exclude BSS.
ram_ok = check_ram ((uint32_t)bss_end, ADDR1M_AREA6_START - 1, TRUE);
if (!ram_ok)
SCI_PRINTF ("heap RAM error.\n");
.bss以降の余った領域のチェック。ヒープとしてあるけど、alloc系は実装しな
い。ターゲットは内蔵RAMだけなので。開発の段階でちょこっと場所が欲しくて
使う用。
// Initialize on-board devices.
board_init ();
switch_test ();
while (/*CONSTCOND*/1)
asm volatile ("sleep");
/* NOTREACHED */
}
I/Oポートについて。
void
ioport_init ()
{
#define IO_DEFAULT 0xff
P4->DDR = IO_DEFAULT;
P4->PCR = 0x0;
P4->DR = 0x0;
SCI_PRINTF ("P4\n");
P5->PCR = 0; // Don't use pull-up MOS.
SCI_PRINTF ("P5\n");
P5のDDRはアドレスラインの設定に関するので、いじってはだめ。タイミング
によってはハングする。
P6->DR = 0; // Internal LED P6-1, P6-2
SCI_PRINTF ("P6\n");
P8->DDR = IO_DEFAULT;
P8->DR = 0x0;
SCI_PRINTF ("P8\n");
P9->DDR = ~0x30; // 4,5 input.
SCI_PRINTF ("P9\n");
SCI0,1と共有。クロックの端子をI/Oポートに割りあてている。SD/MMCカードを
つけることになったらSCK0は明け渡さないといけない...。
PA->DDR = IO_DEFAULT;
PA->DR = 0x0;
SCI_PRINTF ("PA\n");
PAはCSCRのチップセレクトの設定が優先するのでDDRで変更をしてもかまわない。
PB->DDR = IO_DEFAULT;
PB->DR = 0x0;
SCI_PRINTF ("PB\n");
}
