com2w*: allow for higher frequencies than 8MHz

to be used with node S03, which is run at 20MHz.
This commit is contained in:
Martin Preuss
2025-08-18 18:04:30 +02:00
parent 9b1badb310
commit d9e7d4df81
7 changed files with 412 additions and 172 deletions

View File

@@ -92,8 +92,8 @@ ioRawWaitForValidMsg_waitLowLoop1:
.endif
ldi r18, 5
ioRawWaitForValidMsg_waitLowLoop2:
ldi r20, 20 ; wait for about 100us for clock low
rcall com2wWaitForClockLowMulti5Us ; R20, R22
ldi r20, 10 ; wait for about 100us for clock low
rcall com2wWaitForClockLowMulti10Us ; R20, R22
brcs ioRawWaitForValidMsg_recvMsg
dec r18
brne ioRawWaitForValidMsg_waitLowLoop2
@@ -132,8 +132,8 @@ ioRawWaitForValidMsg_end:
; @clobbers R18, R20 (R16, R17, R20, R22, X)
com2wSendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2wWaitForClockLowMulti5Us
ldi r20, 6 ; wait for about 60us for clock low
rcall com2wWaitForClockLowMulti10Us
brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy
rcall com2wClkSetLow ; reserve bus (none)
adiw xh:xl, NETMSG_OFFS_MSGLEN
@@ -267,21 +267,12 @@ com2wRecvByte:
ldi r17, 8
clr r16
com2wRecvByte_loop:
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
brcs com2wRecvByte_waitForClkHigh
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
ldi r20, 30 ; wait up to 300us for clock low
rcall com2wWaitForClockLowMulti10Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_waitForClkHigh:
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
brcs com2wRecvByte_readBit
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
ldi r20, 30 ; wait up to 300us for clock high
rcall com2wWaitForClockHighMulti10Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_readBit:
; handle received bit
inr r18, COM_DATA_INPUT
andi r18, (1<<COM_DATA_PIN)
@@ -360,71 +351,137 @@ com2wDataSetLow:
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockHighMulti5Us
; @routine com2wWaitForClockLowMulti10Us
;
; Wait for high CLK
; Wait for low CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @param R20 multiple of 10us to wait (e.g. "2" for "20" us)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
; @clobbers: r16, r20, r22
com2wWaitForClockHighMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
com2wWaitForClockLowMulti10Us:
.if clock > 1000000
; begin version for > 1000000 Hz
ldi r20, LOW(clock/1000000)
ldi r22, (1<<COM_CLK_PIN)
com2wWaitForClockLowMulti10Us_loop0:
push r20 ; +2
com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
nop ; +1
dec r20 ; +1
brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE
pop r20 ; +2
dec r20 ; +1
brne com2wWaitForClockLowMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE
clc ; +1
ret ; +4
com2wWaitForClockLowMulti10Us_stateReached:
pop r20
sec ; +1
ret ; +4
; end version for > 1000000 Hz
.elif clock < 1000000
.error "Clock speed too low"
.else
.error "Unhandled clock speed"
.endif
; begin version for 1000000 Hz
ldi r22, (1<<COM_CLK_PIN)
com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
com2wWaitForClockHighMulti5Us_loop: ; 5 cycles per loop
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockHighMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockHighMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockHighMulti5Us_stateReached:
sec ; +1
ret ; +4
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
nop ; +1
dec r20 ; +1
brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE
clc ; +1
ret ; +4
com2wWaitForClockLowMulti10Us_stateReached:
sec ; +1
ret ; +4
; end version for 1000000 Hz
.endif
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockLowMulti5Us
; @routine com2wWaitForClockHighMulti10Us
;
; Wait for low CLK
; Wait for high CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @param R20 multiple of 10us to wait (e.g. "2" for "20" us)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
; @clobbers: r16, r20, r22
com2wWaitForClockLowMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
com2wWaitForClockHighMulti10Us:
.if clock > 1000000
; begin version for > 1000000 Hz
ldi r20, LOW(clock/1000000)
ldi r22, (1<<COM_CLK_PIN)
com2wWaitForClockHighMulti10Us_loop0:
push r20 ; +2
com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
breq com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
brne com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
nop ; +1
dec r20 ; +1
brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE
pop r20 ; +2
dec r20 ; +1
brne com2wWaitForClockHighMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE
clc ; +1
ret ; +4
com2wWaitForClockHighMulti10Us_stateReached:
pop r20
sec ; +1
ret ; +4
; end version for > 1000000 Hz
.elif clock < 1000000
.error "Clock speed too low"
.else
.error "Unhandled clock speed"
.endif
; begin version for 1000000 Hz
ldi r22, (1<<COM_CLK_PIN)
com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
breq com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
com2wWaitForClockLowMulti5Us_loop: ; 5 cycles per loop
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockLowMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockLowMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockLowMulti5Us_stateReached:
sec ; +1
ret ; +4
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
and r16, r22 ; +1
brne com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE
nop ; +1
dec r20 ; +1
brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE
clc ; +1
ret ; +4
com2wWaitForClockHighMulti10Us_stateReached:
sec ; +1
ret ; +4
; end version for 1000000 Hz
.endif
; @end