目次

2114アクセススケッチ

 1ワード=4ビットの2114を入手できたので、動作するか
 を調べてみました。



 ピンアサインが不明だと、接続できないので手持ちの
 参考書籍で掲載されているZ80関係の本を利用しました。



 ピンアサインは、以下となっています。



 Arduinoに接続するには、次の3種の信号線群に分けて
 考えます。

 アドレスは動作テストができればよいので、カウンタICを
 挟んで2114と接続します。1kワードとなるので10ビット
 以上の出力をもつ、CMOSの4040を使います。



 カウンタはリセット(ゼロクリア)と+1処理だけができると
 よいので、ポートCのPC0、PC1を使います。



 データは、ポートBのPB3からPB0の4ビットを使います。



 制御は、nCS、nWEがあればよいので、ポートCのPC3、PC2の
 2ビットを使います。



 接続仕様を決めたので、ポートの初期値と入出力方向を
 定義します。

  /* initialize PORT values */
  PORTB = 0x00 ;
  PORTC = 0x0e ;
  PORTD = 0x01 ;
  /* initialize PORT directions */
  DDRB = 0xff ;
  DDRC = 0xff ;
  DDRD = 0xfe ;

 4040の制御には、PC1(CLK)、PC0(RST)を使います。
 リセットは正論理、クロックは負論理として制御用
 に、2関数を定義します。

  #define RST_BIT 0
  #define CLK_BIT 1

  void rst_cnt(void)
  {
    PORTC |=  (1 << RST_BIT);
    PORTC &= ~(1 << RST_BIT);
  }

  void clk_cnt(byte x)
  {
    if ( x ) { PORTC |=  (1 << CLK_BIT); }
    else     { PORTC &= ~(1 << CLK_BIT); }
  }

 4040が、アドレスのゼロクリア、+1を担当するので
 メモリの制御を担当する関数を定義します。

  #define SIG_ENABLE  0
  #define SIG_DISABLE 1

  #define WE_BIT  2
  #define CS_BIT  3

  void cs_2114(byte x)
  {
    if ( x == SIG_ENABLE ) { PORTC &= ~(1 << CS_BIT); }
    else                   { PORTC |=  (1 << CS_BIT); }
  }

  void we_2114(byte x)
  {
    if ( x == SIG_ENABLE ) { PORTC &= ~(1 << WE_BIT); }
    else                   { PORTC |=  (1 << WE_BIT); }
  }

 メモリにデータをライトするには、次のタイミングチャートに
 従って、信号線をON、OFFします。



 データをライトする場合、次のシーケンスを実行します。
  1. アドレス、データを出力
  2. nCSを'L'に下げる
  3. nWEを'L'に下げる
  4. nWEを'H'に上げる
  5. nCSを'H'に上げる
 関数にまとめます。 void put_memory(byte xdat) { /* put data */ PORTC &= 0xf0 ; PORTC |= ((xdat >> 4) & 0x0f) ; PORTB &= 0xf0 ; PORTB |= (xdat & 0x0f) ; /* enable nCS */ cs_2114(SIG_ENABLE) ; /* enable nWE */ we_2114(SIG_ENABLE) ; /* disable nWE */ we_2114(SIG_DISABLE) ; /* disable nCS */ cs_2114(SIG_DISABLE) ; }  アドレスは、ゼロクリアと+1の操作しかないので  関数put_memoryの外で処理します。  データリードのタイミングチャートから  シーケンスを考えます。
  1. アドレス
  2. nCSを'L'に下げる
  3. データ取得
  4. nCSを'H'に上げる
 関数にまとめます。 byte get_memory() { byte dh ; byte dl ; /* change port direction */ DDRC = 0xf0 ; DDRB = 0xf0 ; /* enable nCS */ cs_2114(SIG_ENABLE) ; /* get upper nibble */ dh = PINC & 0x0f ; /* get lower nibble */ dl = PINB & 0x0f ; /* disable nCS */ cs_2114(SIG_DISABLE) ; /* change port direction */ DDRC = 0xff ; DDRB = 0xff ; return( (dh << 4) | dl ) ; }  シリアルポートを利用して、Arduinoにコマンドを  与えて、メモリの操作をしていきます。  コマンドは、以下としました。  コマンドを決めると、インタプリタを定義できます。 if ( uflag == ON ) { /* clear flag */ uflag = OFF ; /* new line */ crlf(); /* get command */ cmd = *(sbuf+0) ; /* judge */ if ( cmd == '?' ) { show_help(); } /* set SRAM contents as 'FF' */ if ( cmd == 'H' ) { /* address zero clear */ rst_cnt(); /* repeat */ for ( cnt = 0 ; cnt < 1024 ; cnt++ ) { /* set data */ put_memory(0xff) ; /* increment */ clk_cnt( ON ); clk_cnt( OFF ); } } /* clear SRAM contens as '00' */ if ( cmd == 'L' ) { /* address zero clear */ rst_cnt(); /* repeat */ for ( cnt = 0 ; cnt < 1024 ; cnt++ ) { /* set data */ put_memory(0x00) ; /* increment */ clk_cnt( ON ); clk_cnt( OFF ); } } /* show SRAM contents */ if ( cmd == 'S' ) { /* address zero clear */ rst_cnt(); /* repeat */ *(msg+2) = 0 ; for ( cnt = 0 ; cnt < 1024 ; cnt++ ) { /* get data */ tmp = get_memory() ; /* convert */ *(msg+0) = get_hex( (tmp >> 4) & 0x0f ) ; *(msg+1) = get_hex( tmp & 0x0f ) ; /* show */ rs_puts( msg ); /* new line */ if ( (cnt % 16) == 15 ) { crlf() ; } /* increment */ clk_cnt( ON ); clk_cnt( OFF ); } } }  コマンドインタプリタ内部で利用している  関数を定義します。 void rs_putchar(char x) { Serial.write(x); } void rs_puts(char *x) { while ( *x ) { rs_putchar(*x); x++ ; } } void crlf(void) { rs_putchar('\r'); rs_putchar('\n'); } void show_help(void) { rs_puts("? help"); crlf(); rs_puts("H set SRAM as FF"); crlf(); rs_puts("L set SRAM as 00"); crlf(); rs_puts("S show SRAM contents"); crlf(); } byte get_hex(char x) { byte result ; /* default */ result = 0 ; /* convert */ if ( '0' <= x && x <= '9' ) { result = x - '0' ; } if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; } if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; } return result ; }  必要な関数は揃ったので、スケッチを定義します。  ただし、2114を2個利用し8ビットデータ幅をもつ  メモリとします。 #define OFF 0 #define ON OFF+1 #define WE_BIT 5 #define CS_BIT 4 #define RST_BIT 5 #define CLK_BIT 4 #define SIG_ENABLE 0 #define SIG_DISABLE 1 #define BSIZE 8 #define MASK0F 0x0f #define MASKF0 0xf0 #define MASKFF 0xff #define LAST 1024 byte uflag ; char sbuf[BSIZE] ; byte sindex ; char cmd ; void rs_putchar(char x) { Serial.write( x ); } void rs_puts(char *ptr) { while ( *ptr ) { rs_putchar( *ptr ); ptr++ ; } } void crlf() { rs_putchar('\r'); rs_putchar('\n'); } void show_help() { rs_puts("? help"); crlf(); rs_puts("H set SRAM as FF"); crlf(); rs_puts("L set SRAM as 00"); crlf(); rs_puts("S show SRAM contents"); crlf(); } byte get_hex(char x) { byte result ; /* default */ result = 0 ; /* convert */ if ( '0' <= x && x <= '9' ) { result = x - '0' ; } if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; } if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; } return result ; } void rst_cnt() { PORTC |= (1 << RST_BIT); PORTC &= ~(1 << RST_BIT); } void clk_cnt(byte x) { if ( x ) { PORTC |= (1 << CLK_BIT); } else { PORTC &= ~(1 << CLK_BIT); } } void cs_2114(byte x) { if ( x == SIG_ENABLE ) { PORTC &= ~(1 << CS_BIT); } else { PORTC |= (1 << CS_BIT); } } void we_2114(byte x) { if ( x == SIG_ENABLE ) { PORTC &= ~(1 << WE_BIT); } else { PORTC |= (1 << WE_BIT); } } void put_memory(byte xdat) { /* put data */ PORTC &= MASKF0 ; PORTC |= ((xdat >> 4) & MASK0F) ; PORTB &= MASKF0 ; PORTB |= (xdat & MASK0F) ; /* enable nCS */ cs_2114(SIG_ENABLE) ; /* enable nWE */ we_2114(SIG_ENABLE) ; /* disable nWE */ we_2114(SIG_DISABLE) ; /* disable nCS */ cs_2114(SIG_DISABLE) ; } byte get_memory() { byte dh ; byte dl ; /* change port direction */ DDRC = MASKF0 ; DDRB = MASKF0 ; /* enable nCS */ cs_2114(SIG_ENABLE) ; /* get upper nibble */ dh = PINC & MASK0F ; /* get lower nibble */ dl = PINB & MASK0F ; /* disable nCS */ cs_2114(SIG_DISABLE) ; /* change port direction */ DDRC = MASKFF ; DDRB = MASKFF ; return( (dh << 4) | dl ) ; } void send_memory(byte x) { word cnt ; /* address zero clear */ rst_cnt(); /* repeat */ for ( cnt = 0 ; cnt < LAST ; cnt++ ) { /* set data */ put_memory( x ) ; /* increment */ clk_cnt( ON ); clk_cnt( OFF ); } } void show_memory() { word cnt ; byte tmp ; char msg[3] ; /* address zero clear */ rst_cnt(); /* repeat */ for ( cnt = 0 ; cnt < LAST ; cnt++ ) { /* get data */ tmp = get_memory() ; /* convert */ *(msg+0) = get_hex( (tmp >> 4) & MASK0F ) ; *(msg+1) = get_hex( tmp & MASK0F ) ; /* show */ rs_puts( msg ); /* new line */ if ( (cnt % 16) == 15 ) { crlf() ; } /* increment */ clk_cnt( ON ); clk_cnt( OFF ); } } void setup() { /* initialize serial port*/ Serial.begin(9600); sindex = 0 ; /* initialize PORT values */ PORTB = 0x00 ; PORTC = 0x0e ; PORTD = 0x01 ; /* initialize PORT directions */ DDRB = 0xff ; DDRC = 0xff ; DDRD = 0xfe ; /* clear flags */ uflag = OFF ; } void loop() { /* command interpreter */ if ( uflag == ON ) { /* clear flag */ uflag = OFF ; /* new line */ crlf(); /* get command */ cmd = *(sbuf+0) ; /* set SRAM contents as 'FF' */ if ( cmd == 'H' ) { send_memory( MASKFF ) ; } /* clear SRAM contens as '00' */ if ( cmd == 'L' ) { send_memory( 0x00 ) ; } /* show SRAM contents */ if ( cmd == 'S' ) { show_memory() ; } } } void serialEvent() { char ch; if ( Serial.available() > 0 ) { /* get 1 charactor */ ch = Serial.read(); /* store */ sbuf[sindex] = ch ; /* increment */ sindex++ ; /* judge */ if ( ch == '\r' ) { sindex = 0 ; uflag = ON ; } } }

目次

inserted by FC2 system