From bf3f2c5f96cdfc7629e93d810f42550349388122 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Thu, 8 May 2008 01:34:25 -0400 Subject: [PATCH] Fix the UART, and set it to 19k2 for more stable operation. Make the downloader a bit more robust. --- Uart.v | 28 +++++++++++-------- binwire.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++---- fpgaboot.asm | 18 ++++++++---- xm.asm | 46 +++++++++++++++---------------- 4 files changed, 122 insertions(+), 48 deletions(-) diff --git a/Uart.v b/Uart.v index 332620b..03db0e1 100644 --- a/Uart.v +++ b/Uart.v @@ -1,5 +1,5 @@ `define IN_CLK 8388608 -`define OUT_CLK 57600 +`define OUT_CLK 19200 `define CLK_DIV `IN_CLK / `OUT_CLK `define DATA_ADDR 16'hFF52 `define STAT_ADDR 16'hFF53 @@ -27,7 +27,7 @@ module UART( reg rx_hasdata = 0; reg [15:0] rx_clkdiv = 0; reg [3:0] rx_state = 4'b0000; - reg [7:0] rx_data; + reg [7:0] rx_data, rx_data_tmp; assign data = (stat_latch) ? {6'b0, rx_hasdata, tx_busy} : (data_latch) ? rx_data : @@ -69,19 +69,23 @@ module UART( rx_state <= 0; case (rx_state) 4'b0001: begin end /* Twiddle thumbs -- this is the end of the half bit. */ - 4'b0010: rx_data[0] <= serialrx; - 4'b0011: rx_data[1] <= serialrx; - 4'b0100: rx_data[2] <= serialrx; - 4'b0101: rx_data[3] <= serialrx; - 4'b0110: rx_data[4] <= serialrx; - 4'b0111: rx_data[5] <= serialrx; - 4'b1000: rx_data[6] <= serialrx; - 4'b1001: rx_data[7] <= serialrx; - 4'b1010: begin end /* Expect a 1 */ + 4'b0010: rx_data_tmp[0] <= serialrx; + 4'b0011: rx_data_tmp[1] <= serialrx; + 4'b0100: rx_data_tmp[2] <= serialrx; + 4'b0101: rx_data_tmp[3] <= serialrx; + 4'b0110: rx_data_tmp[4] <= serialrx; + 4'b0111: rx_data_tmp[5] <= serialrx; + 4'b1000: rx_data_tmp[6] <= serialrx; + 4'b1001: rx_data_tmp[7] <= serialrx; + 4'b1010: if (serialrx == 1) begin + rx_data <= rx_data_tmp; /* Expect a 1 */ + rx_hasdata <= 1; + end endcase end - rx_hasdata <= (rx_hasdata && ~(rd && data_decode)) || ((rx_state == 4'b1010) && (tx_clkdiv == 0)); + if (rd && data_decode) + rx_hasdata <= 0; if(tx_newdata || (tx_clkdiv == `CLK_DIV)) tx_clkdiv <= 0; diff --git a/binwire.c b/binwire.c index 9322ef1..ed6b98c 100644 --- a/binwire.c +++ b/binwire.c @@ -1,4 +1,9 @@ #include +#include +#include +#include +#include +#include void dowrite(char *s, int len) { @@ -9,20 +14,81 @@ void dowrite(char *s, int len) } } -void main() +int waitchar(int timeout) { - char buf[259]; + struct pollfd pfd; + + pfd.fd = 0; + pfd.events = POLLIN; + return poll(&pfd, 1, timeout) == 1; +} + +void expect(char *s, int len) +{ + int i; + char c; + for (i=0; i < len; i++) + { + if (waitchar(100) == 0) + { + fprintf(stderr, "Timeout reached in expect (expected %c)\n", s[i]); + return; + } + while (read(0, &c, 1) == 0) + fprintf(stderr, "Short read...\n"); + if (c != s[i]) + fprintf(stderr, "Expect failed: expected %d, got %d (pos %d)\n", s[i], c, i); + } +} + +void expect_no_chars() +{ + int cs = 0; + + while (waitchar(10) == 1) + { + char c; + if (read(0, &c, 1) == 0) + fprintf(stderr, "enc Short read...\n"); + cs++; + fprintf(stderr, "Warning: expected no chars, got %d\n", c); + } + if (cs) + fprintf(stderr, "Expect no chars failed: got %d chars\n", cs); + + +} + +void main(int argc, char **argv) +{ + unsigned char buf[259]; int sz; + int rfd; + + if (argc < 2) + { + fprintf(stderr, "Usage: %s [filename]\n", argv[0]); + exit(1); + } + rfd = open(argv[1], O_RDONLY); + if (rfd < 0) + { + perror("open"); + exit(1); + } + dowrite("\x1B" "A\x00\x00\x00...", 8); fprintf(stderr, "Address sent\n"); - while ((sz = read(0, buf+3, 128)) > 0) + expect("A...", 4); + while ((sz = read(rfd, buf+3, 128)) > 0) { buf[0] = 0x1B; buf[1] = 'D'; - buf[2] = sz - 1; + buf[2] = sz+1; dowrite(buf, sz + 3); - dowrite(".", 1); fprintf(stderr, "Data sent\n"); - usleep(100000); + expect("D", 1); + expect_no_chars(); } + exit(0); } \ No newline at end of file diff --git a/fpgaboot.asm b/fpgaboot.asm index 0a714b1..6cb9613 100644 --- a/fpgaboot.asm +++ b/fpgaboot.asm @@ -98,20 +98,26 @@ bootcmd: .data: call getc ; byte count ld c, a -.dl: call getc +.dl: dec c + jr z, .done + call getc ld [$FF63], A - dec c - jp nz, .dl - ld A, $44 ;D - ret + jr .dl +.done: ld A, $44 ;D + jr putc + .prog: ld hl, $FF80 ld c, $7F .pl: dec c - jp z, $FF80 + jp z, .progboot call getc ld [hli], a jr .pl +.progboot: + ld a, $50 ;P + call putc + jp $FF80 SECTION "a", HOME[$100] nop ; Make sure we don't overflow. diff --git a/xm.asm b/xm.asm index d4b5374..3a4b25e 100644 --- a/xm.asm +++ b/xm.asm @@ -1,24 +1,23 @@ SECTION "wee",HOME[$0] ; this all needs to be PIC! -st: - ld sp, $CFFF - xor a - ld hl, $FF60 - ld [hli], a - ld [hli], a - ld [hli], a +; xor a +; ld hl, $FF60 +; ld [hli], a +; ld [hli], a +; ld [hli], a +st: ld sp, $CFFF nak: ld a, $15 ; NAK call putc+$FF80 .ack: call getc+$FF80 - cp $01 ;SOH - jr z,.soh +; cp $01 ;SOH +; jr z,.soh cp $04 ;EOT jr z, .eot cp $18 ;CAN jr z, .rst - jr .donak + jr nak .eot: ld A, $06 ; Ack the EOT @@ -27,26 +26,24 @@ nak: .soh: call getc+$FF80 ; blk call getc+$FF80 ; iblk - xor a - ld b, a - ld l, a - ld h, $C0 -.lp: call getc+$FF80 + ld b, $00 + ld hl, $C000 +.lp: bit 7, l + jr nz, .cksm + call getc+$FF80 ld [hli], a add b ld b, a - bit 7, l - jr z, .lp + jr .lp .cksm: call getc+$FF80 cp b jr nz, .donak ld hl, $C000 -.lp2: jr z, .doack - ld a, [hli] +.lp2: ld a, [hli] ld [$FF63], A bit 7, l jr z,.lp2 -.doack: ld A, $06 +.doack: ld A, $06 ; 06 call putc+$FF80 jr .ack .donak: call getc+$FF80 ; Wait until the line clears, and then once @@ -54,7 +51,7 @@ nak: getc: xor d - xor e + ;xor e ; Possibly not needed? .dgetc: dec de xor a @@ -66,11 +63,12 @@ getc: ld a, [$FF52] ret .timeout: - ld hl, $D000 + ld hl, $D010 ld a, [hl] inc a ld [hl], a ld [$FF51], a + pop hl jr nak putc: @@ -84,5 +82,5 @@ putc: ld [$FF52],a ret - section "a", HOME[$7F] - nop \ No newline at end of file + section "a", HOME[$7E] + nop -- 2.39.2