081217

|


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



昨日はなんとなく動かした拡張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");
}