SSブログ
English Version

SuperSimpleController(その12)プリント基板完成 [OriginalCPU]

 前回の記事の冒頭に書いたように「SuperSimpleController(その9)回路図とパターン設計」の記事で書いたプリント基板が製造依頼したElecrowさんから届き、部品実装してみたので記録しておきます。

 製造依頼は5枚ですが6枚届きました(Elecrowさんのいつものサービスですね)
 レジスト色は青にしています。下の写真がトップ面で特に問題ない仕上がりです。今回は10cm四方の基板にかなり詰め込んだので、トラック幅も部分的(SMD IC部品の周辺等)に最小値(0.15mm)に近い0.16mm幅のものを使いましたが問題なく製造されています。

 設計上の問題ですが、LEDのマイナス側を示す二重線が、シルク上ほとんど区別は付かない状態だったので次回はシルクを変更する必要があります。
 また中央上部にあるHALTのLEDの極性が逆でしたw。このLEDは当初RUN LEDとして付けたものをパターン設計中にHALT時に点灯するように変更したものです。

PCBのTOP面



 下の写真はボトム面で左上のSMDタイプの74HC574のICの下側のパスコンが半分程度ICに重なっていましたw。
 設計上のミスですがこのICはトップ面でもほぼ同じ位置に74HC574があるのでトップ面のICとの重なりだけをチェックしてしまっていたようです(部品の3Dデータが揃っていないので3D表示でのチェックはしていなかった^^;)。
 今回はこのパスコンを未実装にして組み立てています。

PCBのBottom面



 手書きのラベルが汚くて恐縮ですが部品実装後のトップ面が下の写真です。
 クロック上限が未評価で当面は外部からクロックを供給して動かすつもりなので水晶は未実装のままです。
 注文していた丸ピンソケットがまだ届いていないので、EEPROMは平ピンソケットを二重に重ねてゼロプレッシャーソケットを付けました。
 ALUのM27C322は42ピンなので32ピンの平ピンソケット+10ピン分削り加工したもので対応しています。

 青色LEDはVf:3V想定で電流制限抵抗を2Kにしましたが、眩しすぎるくらい明るいです(最近の青色LEDはVfが低い?)
 また、halt表示のLEDは通常動作時はDuty10%程度でhalt時にDuty100%になる設計(ハードリソース最小化のため専用の制御信号を待たない節約設計ですw)ですが、通常動作時でも十分明るいのでhalt表示機能としてはイマイチかもしれません。

Top面



 ボトム面が下図で追加で縦方向のトラックが引けないくらい混雑しています。上述のように一部のトラック幅を0.16mmにしていますが、見た目はそれ程細くないように見えますね。

Bottom面



 下の写真は動作中の状態で、前回の記事で書いたHexLoaderを動かしているところです(シリアルI/Fを付けていないのでロードはできない)。
 クロック50Hzで動かすとLE0の点灯状態が目まぐるしく変化して綺麗ですが、クロック1MHzでは変化が殆どありませんw

動作中の様子



★追記 2021/03/28
 Twitterにポストした動画付きコメントを貼っておきます。




[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

SuperSimpleController(その11)HexLoaderの制作 [OriginalCPU]

 前回の記事でシリアル通信ができたことを書きましたが、たまに文字化けが発生する状態でした。
 今回開発しているSimple8Z側の問題なのか調査したところ、PICで生成しているSIO(MC6850)用のクロック精度が悪いことが原因だということが判ったのでPIC内蔵クロックから外付けの8MHzクリスタルに変更したところシリアル通信が安定しました。

 PICのソースも変更したので貼っておきます。

8MHzクリスタルでの9.6KHz生成ソース(PIC12F683)
/* * SIO clock genelator for Simple8Z test008 * PIC12F683 * Ver 0.01 made by skyriver 2021/03/17 */ #include <INT16CXX.H> // define config bit assign(PIC12F683) #define conf_FCMEN (1<<11) // Fail-Safe Clock Monitor Enable #define conf_IESO (1<<10) // Internal External Switchover bit #define conf_BODEN1 (1<<9) // Brown-out Detect Selection bit #define conf_BODEN0 (1<<8) // Brown-out Detect Selection bit #define conf_CPD_ (1<<7) // Data code Protection(0:enable) #define conf_CP_ (1<<6) // Code Protection(0:enable) #define conf_MCLRE (1<<5) // GP3/MCLR_ pin function secet bit(1:MCLR) #define conf_PWRTEN_ (1<<4) // Power-up Timer Enablr bit(0:enable) #define conf_WDTEN (1<<3) // Watchdog Timer enable bit(1:enable) #define conf_FOSC_RC 0b111 #define conf_FOSC_RCIO 0b110 #define conf_FOSC_INTOSC 0b101 #define conf_FOSC_INTOSCIO 0b100 #define conf_FOSC_EC 0b011 #define conf_FOSC_HS 0b010 #define conf_FOSC_XT 0b001 #define conf_FOSC_LP 0b000 //#pragma config = conf_CPD_ | conf_CP_ | conf_FOSC_INTOSCIO #pragma config = conf_CPD_ | conf_CP_ | conf_FOSC_HS /* initialize H/W and workarea */ void init( void ) { GPIO = 0b00000000; // GP0:IntReq WPU = 0b00000000; // 1:Pull-up enable TRISIO = 0b00111011; // 0:output, 1:input CMCON0 = 0b00000111; // Comparator off CMCON1 = 0b00000011; // comp output is asynchronization VRCON = 0b00001000; // Vref is off ANSEL = 0b00000000; // 0:dig, 1:ana OSCCON = 0b01110001; // 8MHz internal clock OPTION = 0b00000000; // PortB_PullUp Fosc/4 T1PreScaler:1/2T WPU = 0b00110111; // PullUp enable // 8000000/(9600*4*1)=208.33 T2CON = 0b0000100; // Timer2 on,pre/post scaler 1:1 PR2 = 208; // (PR2+1)/2 = 104 : duty 50% CCP1CON = 0b00001100; // LSBS:00 PWM mode(active high) CCPR1L = 104; PCON = 0b00000000; } void main( void ) { init(); while ( 1 ) { } }


 今回の自作CPU(Simple8Z)には割込み機能は無いので連続した受信データ(9600bsp)の処理は難しいですが、TeraTermの設定でキャラクタ間に時間を設けてやれば処理できるはずです(TeraTermの設定は5ms/char、20ms/lineにしました)。Simple8Zのクロックも1MHzに上げてみました(上限はもっと高いと思う)。

★2021/04/03 追記 {
 不安定だった原因はJP関連の命令でクリティカルなタイミングがあったためでuCODEを見直したことで安定になりました。1MHzのクロックで動作時にTeraTermの設定が9600bpsで文字毎のウェイト無し(0ms/char)でも取りこぼしが発生しない状態になりました。また、シリアル通信用クロックもPIC内部発信で154.6KHz(=9600x16)付近のクロックを生成することで文字化けもなくなりました。
}

 今後の作業のことも考慮して、まずはヘキサファイルのローダーを作成してみました。前回の記事にマシン語コード表を書きましたが一通りのマシン語を実装したつもりなので、現状のマシン語セットである程度の規模の処理を記述できるかの確認の意味もあります。

 ジャンプ命令でR1レジスタが壊れる等、癖がありますが結果としては何とかできました。メモリ上のワーク領域にある2バイトのアドレスデータの示すメモリにレジスタの内容を書込む処理ができなかったので、ワーク領域の直前にWR_RO命令のオペコードを書いてそこをコールするという方法で対応しましたw

 作成したHexLoaderのリストは下記になります。処理内容としては「Z80GALの構想(その4)簡易モニタの製作」の記事に書いたHexファイルローダーとほぼ同様で、この時はZ80で約120バイトでしたが、今回は約290バイトなので2倍以上のサイズになってしまいました(但し、今回は自動実行の処理を追加している)。
 Simple8Zはレジスタ数が少ない(R0,R1の2個)のでメモリアクセスが多くなることがサイズが大きくなった主な原因だと思います。

作成したSimple8Z用HexLoaderのソース(アセンブリ言語)
;++++++++++++++++++++++++++++++++++++++++ ; Simle8Z HexLoader program ; by skyriver ; V0.01 2021/03/25 ;++++++++++++++++++++++++++++++++++++++++ .xlist include machine.inc .list WORK EQU 0FE00H ; work area on RAM STACK EQU 0FFFFH ; stack low byte STACKP EQU 0FEH ; initial stack low byte value SIO_CMD EQU 0C0H SIO_DAT EQU SIO_CMD + 1 OPWRR0 EQU 050H ; WR_R0 ope code OPRET EQU 0E0H ; RET ope code ASEG ORG 0 START: LD_R0 STACKP ; set stack pointer WR_R0 STACK LD_R1 SIO_CMD ; initialize MC6850 LD_R0 00010111B ; reset cmd OUT_R1_R0 LD_R0 00010100B ; clock x1 OUT_R1_R0 LD_R0 OPWRR0 WR_R0 WRPNT LD_R0 OPRET WR_R0 WRPRET LD_R0 <LOW MSG> CALL PUTS ; display opening message LOAD: CALL GETC LD_R1 ':' CP_R0_R1 JNZ LOAD CALL GBYTE ; get data count WR_R0 COUNT CALL GWORD ; get adr RD_R0 WDATA WR_R0 JPAD RD_R0 <WDATA + 1> ; save first adr to jump adr WR_R0 <JPAD + 1> JP LOAD10 LOADLP: CALL GETC LD_R1 ':' CP_R0_R1 JNZ LOADLP CALL GBYTE ; get data count WR_R0 COUNT CALL GWORD ; get adr LOAD10: CALL GBYTE ; get record type WR_R0 TYPE JZ LOADRD ; if data record DEC_R0 JZ LOADEN ; if end of data LD_R0 <LOW MSGERR> ; type error CALL PUTS HALT LOADEN: CALL DSPTYP ; execute AP LD_R0 <LOW MSGEX> CALL PUTS RD_R0 <JPAD + 1> LDF_R1_R0 RD_R0 JPAD JP_RX LOADRD: CALL GBYTE ; get data byte CALL WRPNT ; write data to memory with adr RD_R0 WDATA INC_R0 WR_R0 WDATA JNC LOAD20 RD_R0 <WDATA + 1> INC_R0 WR_R0 <WDATA + 1> LOAD20: RD_R0 COUNT DEC_R0 WR_R0 COUNT JNZ LOADRD CALL DSPTYP JP LOADLP ; output character to SIO ; R0 <- data PUTC: LDF_R1_R0 ; save data IN_R0 SIO_CMD SHR_R0 SHR_R0 LD_R0_R1 JNC PUTC ; if tx is not ready OUT_R0 SIO_DAT RET ; get char from SIO ; R0 -> data GETC: IN_R0 SIO_CMD CKLSBR0 ; check R0's LSB JNC GETC IN_R0 SIO_DAT RET ; get nible from SIO ; R0 -> data GETNBL: CALL GETC LD_R1 '0' SUB_R0_R1 LD_R1 10 CP_R0_R1 JC GETNB9 LD_R1 <10 + '0' - 'A'> ADD_R0_R1 GETNB9: RET ; get byte data from SIO ; R0 -> data ; ZF -> 1:zero GBYTE: CALL GETNBL SHL_R0 SHL_R0 SHL_R0 SHL_R0 WR_R0 GBYTMP CALL GETNBL LDF_R1_R0 RD_R0 GBYTMP OR_R0_R1 RET ; get word data from SIO ; WDATA -> data GWORD: CALL GBYTE WR_R0 <WDATA + 1> ; save high byte CALL GBYTE WR_R0 WDATA ; save low byte RET ; put string to SIO ; R0 <- pointer ; caution:pointer's high adr is 01H PUTS: DEC_R0 WR_R0 PUTSP PUTSL: RD_R0 PUTSP INC_R0 WR_R0 PUTSP RD_R1_R0 01H LDF_R0_R1 ; if R1 is 0 then set ZF JNZ PUTS10 RET PUTS10: CALL PUTC JP PUTSL if 0 ; disp 1byte with Hex ; R0 <- data DspHxB: WR_R0 DspHx SHR_R0 SHR_R0 SHR_R0 SHR_R0 CALL DspH10 RD_R0 DspHx LD_R1 0FH AND_R0_R1 DspH10: LD_R1 '0' ADD_R0_R1 LD_R1 <'9' + 1> CP_R0_R1 JC PUTC LD_R1 <'A' - 10 - '0'> ADD_R0_R1 JP PUTC endif ; display hex line type ; TYPE <- type data DSPTYP: CALL GBYTE ; read check sum CALL GETC ; read delimitor RD_R0 TYPE LD_R1 '0' ADD_R0_R1 JP PUTC MSG: DB 'HexLoader Start',13,10,0 MSGERR: DB ' err', 13,10,0 MSGEX: DB ' exec',13,10,0 ; ORG WORK ;GBYTMP: DS 1 ; GBYTE's tmp value GBYTMP EQU WORK ;PUTSP: DS 1 ; PUTS's pointer PUTSP EQU GBYTMP + 1 ;TYPE: DS 1 ; Hex line type TYPE EQU PUTSP + 1 ;COUNT: DS 1 ; data count COUNT EQU TYPE + 1 ;JPAD: DS 2 ; jump addr JPAD EQU COUNT + 1 ;WRPNT: DS 1 ; WR_R0 ope code WRPNT EQU JPAD + 2 ;WDATA: DS 2 ; GWORD's return value WDATA EQU WRPNT + 1 ;WRPRET: DS 1 ; RET ope code WRPRET EQU WDATA + 2 ;DspHx DS 1 DspHx EQU WRPRET + 1 ;GETTMP: DS 1 GETRMP EQU DspHx + 1 END


 HexLoader試験のために作成したテストプログラムはHelloを表示する単純なものです。

ローダー試験用プログラム
;++++++++++++++++++++++++++++++++++++++++ ; Simle8Z Loader test program ; by skyriver ; V0.01 2021/03/25 ;++++++++++++++++++++++++++++++++++++++++ .xlist include machine.inc .list START EQU 8000H ; RAM's top address SIO_CMD EQU 0C0H SIO_DAT EQU SIO_CMD + 1 ASEG ORG START LD_R0 <(LOW MSG) - 1> ; x64(4) R0:5F R1:C0 WR_R0 saveR0 ; x75(11) R0:5F R1:00 LOOP: RD_R0 saveR0 ; x86(11) R0:5F R1:00 INC_R0 ; x89(3) R0:60 R1:00 WR_R0 saveR0 ; x100(11) R0:60 R1:00 RD_R1_R0 <HIGH MSG> ; x110(10) R0:60 R1:48 CKZR1 ; x113(3) R0:60 R1:48 LD_R0_R1 ; x116(3) JNZ LOOP1 ; x124(8) R0:60 R1:48 HALT LOOP1: CALL PUTC ; x148(24) JP LOOP ; x214(8) ; output character to SIO ; R0 <- data PUTC: LDF_R1_R0 ; x151(3) IN_R0 SIO_CMD ; x159(8) SHR_R0 ; x162(3) SHR_R0 ; x165(3) LD_R0_R1 ; x168(3) JNC PUTC ; x176(8) if tx not ready OUT_R0 SIO_DAT ; x184(8) RET ; x206(22) MSG: DB "Hello,world", 13,10,0 saveR0: DS 1 END


 上記の試験用プログラムをアセンブル&リンクすることで下記のヘキサファイルが生成されます。

試験用プログラムのアセンブル&リンクで得られたヘキサファイル
:2080000010255034806034803D50348080804F2FC31380FFB01980C004804098C03A3A2F37
:15802000C5198090C1E048656C6C6F2C776F726C640D0A00005D
:00000001FF


 今回作成したHexLoaderはhexFileを1行読む度にレコードタイプを表示するようにしているのでデータ行数分'0'を表示後、終了レコードのレコードタイプである'1'を表示し、ロードしたアプリケーションを実行します。この時の実行アドレスは先頭のデータ行のアドレスにしています。
 HexLoaderを起動し、上記の試験用プログラムのHexFileをロードしている様子が下図の画面キャプチャーです。

HexLoader実行画面例



★追記 2021/03/25
 Twitterにポストした動画付きメッセージを貼っておきます。




[TOP] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

SuperSimpleController(その10)I/O命令追加 [OriginalCPU]

 前回の記事で書いたプリント基板はElecrowさんから昨日(2021/03/20)届いたのですが、手配中の74HCU04のSMDタイプがまだ届いていないので部品待ち状態です。

 今回はI/O関連のマシン語の実装について書いてみます。

 下表がマシン語コード表のアップデート版で橙色の部分が今回追加したマシン語です。マシン語実行時に影響を受けるレジスタを記入した「register」カラムを追記しました。
 従来、CALL命令とRET命令ではR0とR1レジスタが破壊されていましたが、プログラムの実行効率が悪くなるのでR0は保存されるように改善しています(このためRET命令のクロックが20から22に増加した)
 I/O命令でのアドレスは直値の方法とR1レジスタ指定の二通りを実装しました。

 また、I/O命令の他にRX(=R1:R0レジスタペア)とPCとの相互のロード命令とRXへの直値ロード命令も追加しました。

Simple8Z マシン語コード表 第3版

★変更 2021/08/17 "OUT (R1),R0"のクロック数を7から8に変更(VDPSG基板の評価結果を反映)
★変更 2021/04/25 演算処理を考慮して20Hを"LD RX,im16"から"LD R1, R0"に変更
★変更 2021/04/09 メモリライト(WR)命令でクリティカルなタイミングがあったので再度修正
★変更 2021/04/05 メモリライト(WR)命令でクリティカルなタイミングがあったので修正
★変更 2021/04/02 JP命令関連でクリティカルなタイミングがあったので修正
★変更 2021/03/24 「RD_R0 adr16」でR1を保存するように改善


 今回実施したマシン語の試験用ソースのリストが下記になります。
 I/O命令を追加したのでHelloを表示後に入力をエコーバックするというシリアル通信処理を想定した内容にしています。

今回実施した試験プログラム(アセンブリ言語)
;++++++++++++++++++++++++++++++++++++++++ ; Simle8Z test008 program ; by skyriver ; V0.01 2021/03/16 ;++++++++++++++++++++++++++++++++++++++++ .list 8000 RAM EQU 8000H ; RAM's top address FFFF STACK EQU 0FFFFH ; stack low byte 00FE STACKP EQU 0FEH ; initial stack low byte value 00C0 SIO_CMD EQU 0C0H 00C1 SIO_DAT EQU SIO_CMD + 1 0123 JPADR EQU 0123H 0000' ASEG ORG 0 LD_R0 STACKP ; x7 R0:FE R1: 0000 10 + DB 10H 0001 FE + DB STACKP WR_R0 STACK ; x18 R0:FE R1: set stack pointer 0002 50 + DB 50H 0003 FFFF + DW STACK LD_RX JPADR ; x24 R0:23 R1:01 0005 20 + DB 20H 0006 0123 + DW JPADR JP_RX ; x29 R0:23 R1:01 0008 D0 + DB 0D0H ORG JPADR LD_RX_PC ; x34 R0:23 R1:01 0123 D8 + DB 0D8H LD_R1 SIO_CMD ; x38 R0:23 R1:C0 0124 18 + DB 18H 0125 C0 + DB SIO_CMD LD_R0 00010111B ; x42(4) resett R0:17 R1:C0 0126 10 + DB 10H 0127 17 + DB 00010111B OUT_R1_R0 ; x49(7) R0:17 R1:C0 0128 A0 + DB 0A0H LD_R0 00010100B ; x53(4) R0:14 R1:C0 0129 10 + DB 10H 012A 14 + DB 00010100B OUT_R1_R0 ; x60(7) R0:14 R1:C0 012B A0 + DB 0A0H LD_R0 <(LOW MSG) - 1> ; x64(4) R0:5F R1:C0 012C 10 + DB 10H 012D 5E + DB (LOW MSG) - 1 WR_R0 saveR0 ; x75(11) R0:5F R1:00 012E 50 + DB 50H 012F 8000 + DW saveR0 0131 LOOP: RD_R0 saveR0 ; x86(11) R0:5F R1:00 0131 60 + DB 60H 0132 8000 + DW saveR0 INC_R0 ; x89(3) R0:60 R1:00 0134 3D + DB 3DH WR_R0 saveR0 ; x100(11) R0:60 R1:00 0135 50 + DB 50H 0136 8000 + DW saveR0 RD_R1_R0 <HIGH MSG> ; x110(10) R0:60 R1:48 0138 80 + DB 80H 0139 01 + DB HIGH MSG CKZR1 ; x113(3) R0:60 R1:48 013A 4F + DB 4FH LD_R0_R1 ; x116(3) 013B 2F + DB 2FH JZ ECHO ; x124(8) R0:60 R1:48 013C C2 + DB 0C2H 013D 0144 + DW (ECHO) - 1 CALL PUTC ; x148(24) 013F B0 + DB 0B0H 0140 0152 + DW (PUTC) - 1 JP LOOP ; x214(8) 0142 C0 + DB 0C0H 0143 0130 + DW (LOOP) - 1 ; because increment PC after set PC 0145 ECHO: IN_R0 SIO_CMD ; (8) 0145 98 + DB 98H 0146 C0 + DB SIO_CMD SHR_R0 ; (3) 0147 3A + DB 3AH JNC ECHO ; (8) 0148 C5 + DB 0C5H 0149 0144 + DW (ECHO) - 1 IN_R0 SIO_DAT ; (8) 014B 98 + DB 98H 014C C1 + DB SIO_DAT CALL PUTC ; (24) 014D B0 + DB 0B0H 014E 0152 + DW (PUTC) - 1 JP ECHO ; (8) 0150 C0 + DB 0C0H 0151 0144 + DW (ECHO) - 1 ; because increment PC after set PC ; output character to SIO ; R0 <- data ; 0153 PUTC: LDF_R1_R0 ; x151(3) 0153 40 + DB 40H IN_R0 SIO_CMD ; x159(8) 0154 98 + DB 98H 0155 C0 + DB SIO_CMD SHR_R0 ; x162(3) 0156 3A + DB 3AH SHR_R0 ; x165(3) 0157 3A + DB 3AH LD_R0_R1 ; x168(3) 0158 2F + DB 2FH JNC PUTC ; x176(8) if tx not ready 0159 C5 + DB 0C5H 015A 0152 + DW (PUTC) - 1 OUT_R0 SIO_DAT ; x184(8) 015C 90 + DB 90H 015D C1 + DB SIO_DAT RET ; x206(22) 015E E0 + DB 0E0H 015F 48 65 6C 6C MSG: DB "Hello,world", 13,10,0 0163 6F 2C 77 6F 0167 72 6C 64 0D 016B 0A 00 ORG RAM 8000 saveR0: DS 1 END No Fatal error(s)


 折角なので手持ちにあったシリアル通信用チップ(MC68B50)をブレッドボード上で仮接続して試験しました。通信用クロックはPIC12F683を使って9.6KHzを生成し、MC68B50に供給しています。

シリアル通信用クロックgenelator(PIC12F683)
/* SIO clock genelator for Simple8Z test008 * PIC12F683 * Ver 0.01 made by skyriver 2021/03/17 */ #include <INT16CXX.H> // define config bit assign(PIC12F683) #define conf_FCMEN (1<<11) // Fail-Safe Clock Monitor Enable #define conf_IESO (1<<10) // Internal External Switchover bit #define conf_BODEN1 (1<<9) // Brown-out Detect Selection bit #define conf_BODEN0 (1<<8) // Brown-out Detect Selection bit #define conf_CPD_ (1<<7) // Data code Protection(0:enable) #define conf_CP_ (1<<6) // Code Protection(0:enable) #define conf_MCLRE (1<<5) // GP3/MCLR_ pin function secet bit(1:MCLR) #define conf_PWRTEN_ (1<<4) // Power-up Timer Enablr bit(0:enable) #define conf_WDTEN (1<<3) // Watchdog Timer enable bit(1:enable) #define conf_FOSC_RC 0b111 #define conf_FOSC_RCIO 0b110 #define conf_FOSC_INTOSC 0b101 #define conf_FOSC_INTOSCIO 0b100 #define conf_FOSC_EC 0b011 #define conf_FOSC_HS 0b010 #define conf_FOSC_XT 0b001 #define conf_FOSC_LP 0b000 #pragma config = conf_CPD_ | conf_CP_ | conf_FOSC_INTOSCIO /* initialize H/W and workarea */ void init( void ) { GPIO = 0b00000000; // GP0:IntReq WPU = 0b00000000; // 1:Pull-up enable TRISIO = 0b00111011; // 0:output, 1:input CMCON0 = 0b00000111; // Comparator off CMCON1 = 0b00000011; // comp output is asynchronization VRCON = 0b00001000; // Vref is off ANSEL = 0b00000000; // 0:dig, 1:ana OSCCON = 0b01110001; // 8MHz internal clock OPTION = 0b00000000; // PortB_PullUp Fosc/4 T1PreScaler:1/2T WPU = 0b00110111; // PullUp enable // 8000000/(9600*4) = 208.3 T2CON = 0b0000100; // Timer2 on,pre/post scaler 1:1 PR2 = 208; // (PR2+1)/2 = 104 : duty 50% CCP1CON = 0b00001100; // LSBS:00 PWM mode(active high) CCPR1L = 104; PCON = 0b00000000; } void main( void ) { init(); while ( 1 ) { } }


 MC68B50のE信号(チップイネーブル)は正論理なので本来ならSimple8Zの外部接続用コネクタ内のIOR/信号(MEM/信号を反転したもの)を反転して接続すべきですが、動作試験ということでMEM/信号を直接接続しました。

追加したシリアルチップ(MC68B50)


 試験用ソフト内のPUTC処理のRET命令実行直後に停止させた際のロジアナ画面が下図になります。
 12:IRW/が命令フェッチ信号でこの信号が0の箇所がマシン語の区切りです。

試験用ソフト実行時のロジアナ画面例



 シリアル通信で"Hello"の最初の'H'を出力している部分を拡大したものが下図です。
 確かに'H'が出力されています^^

試験用ソフト実行時のロジアナ画面例('H'出力部)



★追記 2021/03/22 {
 上図ではディバッグのためにクロックを50Hzにしているので'H'のシリアル出力時間と比較しCPUの動作がかなり遅くなっています。クロックを約130KHzにした場合のロジアナ波形が下図になります。クロック上限は未評価です。

クロック約130KHzでの'H'出力

}

 上記の試験用ソースにあるエコーバック部分に関してはまだ動作確認できていませんが、MC68B50のTxDataとRxDataにシリアルUSB変換モジュールを接続してTeraTermでモニタした結果が下図になります。

 CPUボードを組み立てた際に多くの人が出力するであろうなんの変哲もないただのハロー表示画面ですが、今回は自作のCPUで出したものなので感慨深いものがありますね。

Simple8Zでの初めてのHello,world



★追記 2021/03/22
 エコーバック試験も通りました^^
 ノートPCのTeraTermのバックカラーは暗かったということが判ったw

エコーバックもOK




[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 

SuperSimpleController(その9)回路図とパターン設計 [OriginalCPU]

 前回の記事で書いたようにマシン語の実装も概ねできて(今後I/O関連等のマシン語を追加予定)ハード的にも安定しているようなので回路図の整理とパターン設計を行いました。

 結果として13チップ構成となり 10cm x 10cm のプリント基板にかろうじて実装することができました^^
 外部とのインターフェースは実装できなかったのでI/Oインターフェースとしてアドレス、データ及び最小限の制御信号をコネクタ接続できるようにしています。
 この外部インターフェースのコネクタの信号配列は Simple8 というバス仕様に準拠しました(オリジナルCPUの名前を決めるためのグーグラビリティの確認時に見つけたw)

 今までの評価で多少の変更があったのでブロック図も更新しました。この図から構成チップと回路図の大枠が判るのではないかと思います。

Simple8Z概要ブロック図

★変更 2021/11/03 ブロック図を最新版にアップデート


 今回のオリジナルCPUは上述のように13チップ構成で、4itCPUでメジャーなTD4が14チップ構成なので64KBのメモリ空間を有する8bitCPUとしてはかなりシンプルな回路にできたのではないでしょうか?
★追記 2021/03/15
 上記のTD4のチップ数はネット上にあった制作例の写真からカウントしましたが「CPUの創りかた」の書籍の表紙には”IC10個のお手軽CPU”との記載がありました


 「開発環境について」の記事で書いたように動作確認時に外部からクロックとリセット信号を供給することで任意時点で動作停止できていたのでこの環境も継続して使えるようにジャンパーピンを追加しました。クロックは1MHz付近までは動くことを確認しましたが、上限は未確認です。またLEDの電流制限抵抗値等も今後見直す可能性があります(手配中のLEDがきたら実験予定)
 詳細は下記の回路図を参照してください。

Simple8Zの回路図
★変更 2021/11/03 最新版にアップデート


 パターン設計はかなり難航(特に縦方向の経路が殆どなくなった)しましたが、詰む寸前で最後のトラックを何とか通すことができました^^

 HC574周りは最小トラック幅(0.16mm:Elecrowでは0.15mmですがFusion PCBでは6milで切り上げ計算すると0.16mm)で配線しましたがviaの最小幅が0.6mm(ホール0.3mmで枠が0.15mmx2)なのでトラック間の隙間もある程度必要になり、top面とbottom面で縦横直行パターンにするより斜めにしてviaを少なくした方が効率がいい場合もあることが判りました。

 DesignSparkPCBでのSpaceingsのチェック設定は下表の値で通しています。



 尚、DCプラグのGND端子の中央部分で下記のエラーが最後まで取れませんでしたが、拡大表示して該当するようなパターンもなく、悪さしそうもないのでそのままにしていますw

Dangling Track from (538.40,542.08) to (538.54,542.29) on layer Top Copper


 完成したプリント基板のパターンが下図になります。
 緑色の部分はグランドです。未結線であることを示す細い線が残っていますが、グランドをベタパターンにする時点で接続されます(孤立した場合はviaを打ってつなげる)

完成したプリント基板のパターン(グランドベタ化前)


 グランドベタ化後のトップ面とボトム面が下図になります。

トップ面(グランドベタ化後)


ボトム面(グランドベタ化後)


 去年の暮れ頃にElecrowさんにPic24V20の基板を手配した際に貰った555ポイントがまだ有効だったのでElecrowさんに本日製造依頼しました。
 100ポイントで1ドル相当でポイント適用を555で入力したら1回に使えるポイント数は購入価格の40%までのようでポイントで-$1.96値引きされ、未使用分は残ポイントとして残りました。

Subtotal $4.90
Rewardpoints(Used 196)-$1.96
Shipping & Handling$13.90
Estimated Total$16.84


 また、今回は5枚製造依頼し、基板の厚さをちょっと薄めの1.2mmにしてみました(軽い方が輸送費が安くなるw)。
 輸送方法は安めのOCS/ANA Express(3-5 Business Days)にしています(因みにDHLでは$18.72)

 最後にElecrowさんに依頼する際に必要になる設計データファイルのリネームについてDesignSparkPCBの出力ファイル名との対応をメモしておきます。

No.DSPCB outputnew file name
1Simple8Z001 - Top Copper.gbrSimple8Z001.GTL
2Simple8Z001 - Top Silkscreen.gbrSimple8Z001.GTO
3Simple8Z001 - Top Copper (Resist).gbrSimple8Z001.GTS
4Simple8Z001 - Bottom Copper.gbrSimple8Z001.GBL
5Simple8Z001 - Bottom Silkscreen.gbrSimple8Z001.GBO
6Simple8Z001 - Bottom Copper (Resist).gbrSimple8Z001.GBS
7Simple8Z001 - Drill Data - [Through Hole].drlSimple8Z001.TXT
8Simple8Z001 - Outline.gbrSimple8Z001.GML



★追記 2021/04/17
 構成チップ一覧表を追記します。

構成チップ一覧




[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー