avr: tweaked timing for com2w transport layer.

This commit is contained in:
Martin Preuss
2025-08-19 23:03:15 +02:00
parent 102996f69f
commit fc073696f8
15 changed files with 311 additions and 189 deletions

View File

@@ -170,6 +170,7 @@ com2wReceiveNextPkg_end:
#if 0
; ---------------------------------------------------------------------------
; @routine com2wReceiveAndCheckMsg
;
@@ -208,6 +209,7 @@ com2wReceiveAndCheckMsg_msgOk:
sec
ret
; @end
#endif
@@ -247,9 +249,9 @@ com2wSendNextPkg_end:
; @clobbers R16, R18 (R20, R22, R24, R25, X)
com2wSendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2wWaitForClockLowMulti5Us
brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy
ldi r20, 6 ; wait for about 60us for clock low
rcall com2wWaitForClockLowMulti10Us ; (R16, R20, R22)
brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy
push r15
in r15, SREG
cli ; atomic disable irq and set CLK low
@@ -313,7 +315,7 @@ com2wSendByte:
ldi r17, 8
com2wSendByte_loop:
rcall com2wClkSetLow
rcall com2wWaitTime1 ; longer wait period (R22)
rcall com2wWaitTime2 ; shorter wait period (R22)
lsr r16
brcs com2wSendByte_send1
rcall com2wDataSetLow
@@ -321,12 +323,12 @@ com2wSendByte_loop:
com2wSendByte_send1:
rcall com2wDataSetHigh
com2wSendByte_sent:
rcall com2wWaitTime2 ; shorter wait period (R22)
Utils_WaitNanoSecs 5000, 0, r22 ; wait for very short time to ensure data is stable when clock rises
push r15
in r15, SREG
cli ; ensure time period by disabling irqs
rcall com2wClkSetHigh
rcall com2wWaitTime1 ; longer wait period (R22)
rcall com2wWaitTime2 ; shorter wait period (R22)
out SREG, r15
pop r15
dec r17
@@ -416,21 +418,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, 50 ; wait up to 500us for clock low
rcall com2wWaitForClockLowMulti10Us ; (R16, 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, 50 ; wait up to 500us for clock high
rcall com2wWaitForClockHighMulti10Us ; (R16, R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_readBit:
; handle received bit
inr r18, COM_DATA_INPUT
andi r18, (1<<COM_DATA_PIN)
@@ -544,71 +537,121 @@ com2wDataSetLow:
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockHighMulti5Us
; @routine com2wWaitForClockHighMulti10Us
;
; 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
com2wWaitForClockHighMulti5Us:
.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 r22, clock/1000000
com2wWaitForClockHighMulti10Us_loop0:
push r20
com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken)
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken)
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken)
nop ; +1
dec r20 ; +1
brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE
pop r20
dec r22 ; +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"
; begin version for 1000000 Hz
com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken)
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken)
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken)
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
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
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockLowMulti5Us
; @routine com2wWaitForClockLowMulti10Us
;
; 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
com2wWaitForClockLowMulti5Us:
.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 r22, clock/1000000
com2wWaitForClockLowMulti10Us_loop0:
push r20
com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken)
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken)
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken)
nop ; +1
dec r20 ; +1
brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE
pop r20
dec r22 ; +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"
; begin version for 1000000 Hz
com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken)
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken)
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken)
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
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
; @end