mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-23 18:18:07 +11:00
recipes/arduinouno/at28: improve reliability
Previously, it could never write more than a few bytes before pingpong getting a mismatch error. Now, I can pingpong Collapse OS binary without a mismatch.
This commit is contained in:
parent
bc1cc591ce
commit
b8e52707e9
@ -14,10 +14,10 @@ all: $(TARGET)
|
|||||||
@echo Done!
|
@echo Done!
|
||||||
|
|
||||||
send: $(PROGNAME).hex
|
send: $(PROGNAME).hex
|
||||||
avrdude $(AVRDUDEARGS) -p $(AVRDUDEMCU) -U flash:w:$<
|
avrdude $(AVRDUDEARGS) -p $(AVRDUDEMCU) -U flash:w:$(PROGNAME).hex
|
||||||
|
|
||||||
$(TARGET): at28wr.asm
|
$(TARGET): $(PROGNAME).asm
|
||||||
$(AVRA) -o $@ at28wr.asm
|
$(AVRA) -o $@ $(PROGNAME).asm
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGET) *.S.eep.hex *.S.obj
|
rm -f $(TARGET) *.S.eep.hex *.S.obj
|
||||||
|
@ -23,6 +23,11 @@ on the Arduino's right side (except for VCC, which needs to be wired).
|
|||||||
|
|
||||||
PD0 and PD1 are not used because they're used for the UART.
|
PD0 and PD1 are not used because they're used for the UART.
|
||||||
|
|
||||||
|
AT28 selection pins are pulled up to avoid accidental writes due to their line
|
||||||
|
floating before Arduino's initialization.
|
||||||
|
|
||||||
|
I've put 1uf decoupling caps next to each IC.
|
||||||
|
|
||||||
## Software
|
## Software
|
||||||
|
|
||||||
The software in at28wr.asm listens to the UART and writes every byte it receives
|
The software in at28wr.asm listens to the UART and writes every byte it receives
|
||||||
|
@ -8,6 +8,17 @@
|
|||||||
; with PD7:2 for bits 7:2 and PB1:0 for bits 1:0 (PD1 and PD0 are used for
|
; with PD7:2 for bits 7:2 and PB1:0 for bits 1:0 (PD1 and PD0 are used for
|
||||||
; UART).
|
; UART).
|
||||||
;
|
;
|
||||||
|
; *** Timing, matching and CE ***
|
||||||
|
;
|
||||||
|
; A lot of trial-and-errors went into those NOPs being place to give time for
|
||||||
|
; latching. All these timing are well, well above maximums given in the specs,
|
||||||
|
; but when I wasn't going well, well above those specs, I was experiencing
|
||||||
|
; read/write errors. It seems we live in an imperfect world!
|
||||||
|
;
|
||||||
|
; I'm also not sure, in "writedata", whether toggling CE along with WE is
|
||||||
|
; actually needed, but until I did, I was experiencing random write failures.
|
||||||
|
; So, we end up with this...
|
||||||
|
;
|
||||||
; *** Register Usage ***
|
; *** Register Usage ***
|
||||||
;
|
;
|
||||||
; r0: holds whether last received char was tty-escaped (0 = no, 1=yes)
|
; r0: holds whether last received char was tty-escaped (0 = no, 1=yes)
|
||||||
@ -92,6 +103,10 @@ sendaddr:
|
|||||||
|
|
||||||
; send r20 to EEPROM's I/O7:0 through PD7:2 and PB1:0
|
; send r20 to EEPROM's I/O7:0 through PD7:2 and PB1:0
|
||||||
writedata:
|
writedata:
|
||||||
|
cbi PORTB, FLCE
|
||||||
|
; addr is latched on WE falling edge
|
||||||
|
cbi PORTB, FLWE
|
||||||
|
|
||||||
; send bits 7:2
|
; send bits 7:2
|
||||||
mov r16, r20
|
mov r16, r20
|
||||||
andi r16, 0xfc
|
andi r16, 0xfc
|
||||||
@ -106,49 +121,59 @@ writedata:
|
|||||||
andi r17, 0xfc
|
andi r17, 0xfc
|
||||||
or r16, r17
|
or r16, r17
|
||||||
out PORTB, r16
|
out PORTB, r16
|
||||||
|
|
||||||
|
; data is latched on rising edge
|
||||||
|
sbi PORTB, FLWE
|
||||||
|
sbi PORTB, FLCE
|
||||||
|
nop ; Give the AT28 time to latch
|
||||||
|
nop
|
||||||
|
nop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; push r20 to the rom and increase the memory counter
|
; push r20 to the rom and increase the memory counter
|
||||||
pushdata:
|
nextaddr:
|
||||||
; first, set up addr
|
; first, set up addr
|
||||||
mov r23, r21
|
mov r23, r21
|
||||||
rcall sendaddr
|
rcall sendaddr
|
||||||
mov r23, r22
|
mov r23, r22
|
||||||
rcall sendaddr
|
rcall sendaddr
|
||||||
inc r22
|
inc r22
|
||||||
brne pushdata_0 ; no overflow? skip
|
brne nextaddr_0 ; no overflow? skip
|
||||||
inc r21
|
inc r21
|
||||||
|
nextaddr_0:
|
||||||
pushdata_0:
|
|
||||||
; addr is latched on WE falling edge
|
|
||||||
cbi PORTB, FLWE
|
|
||||||
|
|
||||||
; now, lets set up data. Plenty enough instructions to ensure a 100ns
|
|
||||||
; minimum delay.
|
|
||||||
rcall writedata
|
|
||||||
|
|
||||||
; data is latched on rising edge
|
|
||||||
sbi PORTB, FLWE
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; wait until I/O7 stops toggling
|
; wait until I/O7 stops toggling
|
||||||
waitio7:
|
waitio7:
|
||||||
|
cbi PORTB, FLCE
|
||||||
cbi PORTB, FLOE
|
cbi PORTB, FLOE
|
||||||
|
nop ; Give the AT28 time to latch
|
||||||
|
nop
|
||||||
|
nop
|
||||||
in r16, PIND
|
in r16, PIND
|
||||||
sbi PORTB, FLOE
|
sbi PORTB, FLOE
|
||||||
|
sbi PORTB, FLCE
|
||||||
andi r16, 0xfc
|
andi r16, 0xfc
|
||||||
|
cbi PORTB, FLCE
|
||||||
cbi PORTB, FLOE
|
cbi PORTB, FLOE
|
||||||
|
nop ; Give the AT28 time to latch
|
||||||
|
nop
|
||||||
|
nop
|
||||||
in r17, PIND
|
in r17, PIND
|
||||||
sbi PORTB, FLOE
|
sbi PORTB, FLOE
|
||||||
|
sbi PORTB, FLCE
|
||||||
andi r17, 0xfc
|
andi r17, 0xfc
|
||||||
cp r16, r17
|
cp r16, r17
|
||||||
brne waitio7
|
brne waitio7
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; read EEPROM's I/O7:0 through PD7:2 and PB1:0 and put result in r20.
|
; read EEPROM's I/O7:0 through PD7:2 and PB1:0 into r20
|
||||||
readdata:
|
readdata:
|
||||||
|
cbi PORTB, FLCE
|
||||||
cbi PORTB, FLOE
|
cbi PORTB, FLOE
|
||||||
|
nop ; Give the AT28 time to latch
|
||||||
|
nop
|
||||||
|
nop
|
||||||
; read bits 7:2
|
; read bits 7:2
|
||||||
in r20, PIND
|
in r20, PIND
|
||||||
andi r20, 0xfc
|
andi r20, 0xfc
|
||||||
@ -157,13 +182,14 @@ readdata:
|
|||||||
andi r16, 0x03
|
andi r16, 0x03
|
||||||
or r20, r16
|
or r20, r16
|
||||||
sbi PORTB, FLOE
|
sbi PORTB, FLOE
|
||||||
|
sbi PORTB, FLCE
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Set PD7:2 and PB1:0 to output
|
; Set PD7:2 and PB1:0 to output
|
||||||
ioout:
|
ioout:
|
||||||
ldi r16, 0xfc ; PD7:2
|
ldi r16, 0xfc ; PD7:2
|
||||||
out DDRD, r16
|
out DDRD, r16
|
||||||
ldi r16, 0x3f ; PB5:0 (WE, OE and CE too)
|
ldi r16, 0x3f ; PB5:0 (CP, WE, OE and CE too)
|
||||||
out DDRB, r16
|
out DDRB, r16
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -181,11 +207,9 @@ main:
|
|||||||
ldi r16, high(RAMEND)
|
ldi r16, high(RAMEND)
|
||||||
out SPH, r16
|
out SPH, r16
|
||||||
|
|
||||||
; We begin with WE and OE disabled (high), but CE stays enabled (low)
|
|
||||||
; the whole time.
|
|
||||||
sbi PORTB, FLWE
|
sbi PORTB, FLWE
|
||||||
sbi PORTB, FLOE
|
sbi PORTB, FLOE
|
||||||
cbi PORTB, FLCE
|
sbi PORTB, FLCE
|
||||||
|
|
||||||
; Clear counters and flags
|
; Clear counters and flags
|
||||||
clr r0
|
clr r0
|
||||||
@ -204,7 +228,8 @@ main:
|
|||||||
loop:
|
loop:
|
||||||
rcall uartrd
|
rcall uartrd
|
||||||
rcall ioout
|
rcall ioout
|
||||||
rcall pushdata
|
rcall nextaddr
|
||||||
|
rcall writedata
|
||||||
rcall ioin
|
rcall ioin
|
||||||
rcall waitio7
|
rcall waitio7
|
||||||
rcall readdata
|
rcall readdata
|
||||||
|
@ -12,7 +12,7 @@ properly set up, TTY-wise. You'll probably want to do that with `stty`. The tool
|
|||||||
itself takes care of setting the regular stuff (`cs8`, `-parenb`, etc), but you
|
itself takes care of setting the regular stuff (`cs8`, `-parenb`, etc), but you
|
||||||
need to set the speed. Here's an example working on OpenBSD:
|
need to set the speed. Here's an example working on OpenBSD:
|
||||||
|
|
||||||
$ ( stty 115200 ; ./upload - a000 os.bin ) <>/dev/cuaU0
|
$ ( stty 115200 raw ; ./upload - a000 os.bin ) <>/dev/cuaU0
|
||||||
|
|
||||||
To be honest, I'm having a bit of troubles making these tools work as well on
|
To be honest, I'm having a bit of troubles making these tools work as well on
|
||||||
OpenBSD as they do in Linux. But it *does* work. Here are some advices:
|
OpenBSD as they do in Linux. But it *does* work. Here are some advices:
|
||||||
|
Loading…
Reference in New Issue
Block a user