com2w*: allow for higher frequencies than 8MHz
to be used with node S03, which is run at 20MHz.
This commit is contained in:
@@ -100,7 +100,7 @@ com2wnInit:
|
||||
rcall com2wSetMode ; (R17)
|
||||
|
||||
rcall com2wSetupLines
|
||||
rcall com2wSetupIrq
|
||||
rcall com2wnSetupIrq
|
||||
|
||||
ret
|
||||
; @end
|
||||
|
||||
@@ -34,7 +34,7 @@ com2wSetupLines:
|
||||
.endif
|
||||
|
||||
; setup DATA line (as input, disable internal pull-up resistor)
|
||||
rcall com2wDataSetHigh
|
||||
rcall com2wnDataSetHigh
|
||||
.ifdef COM_DATA_PUE
|
||||
ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_DATA
|
||||
com r16
|
||||
@@ -75,12 +75,12 @@ com2wClkSetHigh:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wClkSetLow
|
||||
; @routine com2wnClkSetLow
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers none
|
||||
|
||||
com2wClkSetLow:
|
||||
com2wnClkSetLow:
|
||||
push r16
|
||||
push r17
|
||||
ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_CLK
|
||||
@@ -102,12 +102,12 @@ com2wClkSetLow:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wDataSetHigh
|
||||
; @routine com2wnDataSetHigh
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers none
|
||||
|
||||
com2wDataSetHigh:
|
||||
com2wnDataSetHigh:
|
||||
push r16
|
||||
push r17
|
||||
ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_DATA
|
||||
@@ -129,12 +129,12 @@ com2wDataSetHigh:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wDataSetLow
|
||||
; @routine com2wnDataSetLow
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers none
|
||||
|
||||
com2wDataSetLow:
|
||||
com2wnDataSetLow:
|
||||
push r16
|
||||
push r17
|
||||
ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_DATA
|
||||
|
||||
@@ -23,12 +23,16 @@ com2wnSetupIrq:
|
||||
; setup pin-change interrupt for CLK
|
||||
rcall com2wnEnableClkIrq
|
||||
|
||||
; enable and clear PCIE0/1 (@TODO put later into general setup)
|
||||
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
sbr r16, (1<<COM_IRQ_GIMSK_CLK)
|
||||
outr GIMSK, r16
|
||||
ldi r16, (1<<COM_IRQ_GIFR_CLK) ; clear pending irq by writing 1 to GIFR bit
|
||||
outr GIFR, r16
|
||||
; enable PCIEn irq
|
||||
inr r16, COM_IRQ_ADDR_M_CLK ; enable pin change irq PCIEn
|
||||
sbr r16, (1<<COM_IRQ_BIT_M_CLK)
|
||||
outr COM_IRQ_ADDR_M_CLK, r16
|
||||
|
||||
; clear PCIEn interrupt flag
|
||||
inr r16, COM_IRQ_ADDR_F_CLK ; enable pin change irq PCIEn
|
||||
sbr r16, (1<<COM_IRQ_BIT_F_CLK)
|
||||
outr COM_IRQ_ADDR_F_CLK, r16
|
||||
|
||||
ret
|
||||
; @end
|
||||
|
||||
@@ -74,14 +78,16 @@ com2wnDisableClkIrq:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine COM2WN_ClkChangeOnePortIsr @global @isr
|
||||
; @routine COM2WN_ClkChangeIsr @global @isr
|
||||
;
|
||||
; Interrupt service routine for single port (i.e. one port contains all
|
||||
; CLOCK and DATA bits like in node R05).
|
||||
; Interrupt service routine for dual or single port (i.e. one port contains all
|
||||
; CLOCK and DATA bits like in node R05 and R06).
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
COM2WN_ClkChangeOnePortIsr:
|
||||
COM2WN_ClkChangeIsr:
|
||||
.if COM_DATA_INPUT == COM_CLK_INPUT
|
||||
; routine for single port
|
||||
push r15
|
||||
in r15, SREG
|
||||
push r16
|
||||
@@ -95,11 +101,11 @@ COM2WN_ClkChangeOnePortIsr:
|
||||
ldi yl, LOW(com2wnIoRingBuffer)
|
||||
ldi yh, HIGH(com2wnIoRingBuffer)
|
||||
rcall RingBufferY_WriteByte ; (R17, R18, X)
|
||||
brcs COM2WN_ClkChangeOnePortIsr_popRet
|
||||
brcs COM2WN_ClkChangeIsr_popRet
|
||||
lds r16, com2wnIoFlags
|
||||
ori r16, (1<<COM2W_IO_FLAGS_BIT_OVR)
|
||||
sts com2wnIoFlags, r16
|
||||
COM2WN_ClkChangeOnePortIsr_popRet:
|
||||
COM2WN_ClkChangeIsr_popRet:
|
||||
pop yh
|
||||
pop yl
|
||||
pop xh
|
||||
@@ -110,19 +116,8 @@ COM2WN_ClkChangeOnePortIsr_popRet:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine COM2WN_ClkChangeTwoPortIsr @global @isr
|
||||
;
|
||||
; Interrupt service routine for single port (i.e. one port contains all
|
||||
; CLOCK and DATA bits like in node R05).
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
COM2WN_ClkChangeTwoPortIsr:
|
||||
.else
|
||||
; routine for two port
|
||||
push r15
|
||||
in r15, SREG
|
||||
push r16
|
||||
@@ -139,14 +134,14 @@ COM2WN_ClkChangeTwoPortIsr:
|
||||
push r17
|
||||
rcall RingBufferY_WriteByte ; push clk state (R17, R18, X)
|
||||
pop r16 ; pop DATA input into r16 (from r17)
|
||||
brcc COM2WN_ClkChangeTwoPortIsr_ovr
|
||||
brcc COM2WN_ClkChangeIsr_ovr
|
||||
rcall RingBufferY_WriteByte ; push data state (R17, R18, X)
|
||||
brcs COM2WN_ClkChangeTwoPortIsr_popRet
|
||||
COM2WN_ClkChangeTwoPortIsr_ovr:
|
||||
brcs COM2WN_ClkChangeIsr_popRet
|
||||
COM2WN_ClkChangeIsr_ovr:
|
||||
lds r16, com2wnIoFlags
|
||||
ori r16, (1<<COM2W_IO_FLAGS_BIT_OVR)
|
||||
sts com2wnIoFlags, r16
|
||||
COM2WN_ClkChangeTwoPortIsr_popRet:
|
||||
COM2WN_ClkChangeIsr_popRet:
|
||||
pop yh
|
||||
pop yl
|
||||
pop xh
|
||||
@@ -157,6 +152,8 @@ COM2WN_ClkChangeTwoPortIsr_popRet:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
|
||||
.endif
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
@@ -18,15 +18,97 @@
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine COM2WN_Run
|
||||
;
|
||||
; @return CFLAG set if something done, cleared otherwise
|
||||
; @clobbers all
|
||||
|
||||
COM2WN_Run:
|
||||
clr r16
|
||||
; first handle lowlevel (e.g. handle all CLK changes and DATA from ringbuffer)
|
||||
COM2WN_Run_loop1:
|
||||
push r16
|
||||
rcall com2wnLowLevelRun
|
||||
pop r16
|
||||
brcc COM2WN_Run_handleRunModes
|
||||
rcall com2wnSetR16OnCarrySet
|
||||
rjmp COM2WN_Run_loop1
|
||||
|
||||
; then handle messages etc
|
||||
COM2WN_Run_handleRunModes:
|
||||
ldi r19, COM_PORTS
|
||||
ldi yl, LOW(com2w0_iface) ; first interface
|
||||
ldi yh, HIGH(com2w0_iface)
|
||||
COM2WN_Run_loop2:
|
||||
push r16
|
||||
push r19
|
||||
rcall com2wnRunMode ; (clobbers possibly all but Y)
|
||||
pop r19
|
||||
pop r16
|
||||
rcall com2wnSetR16OnCarrySet
|
||||
ldi r20, COM2W_IFACE_SIZE
|
||||
add yl, r20
|
||||
adc yh, r20
|
||||
sub yh, r20
|
||||
dec r19
|
||||
brne COM2WN_Run_loop2
|
||||
tst r16
|
||||
clc
|
||||
breq COM2WN_Run_ret
|
||||
sec
|
||||
COM2WN_Run_ret:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wnSetR16OnCarrySet
|
||||
;
|
||||
|
||||
com2wnSetR16OnCarrySet:
|
||||
brcc com2wnSetR16OnCarrySet_ret
|
||||
ldi r16, 1
|
||||
com2wnSetR16OnCarrySet_ret:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine COM2WN_Periodically
|
||||
;
|
||||
|
||||
COM2WN_Periodically:
|
||||
ldi r19, COM_PORTS
|
||||
ldi yl, LOW(com2w0_iface) ; first interface
|
||||
ldi yh, HIGH(com2w0_iface)
|
||||
COM2WN_Periodically_loop: ; loop through all interfaces
|
||||
push r19
|
||||
rcall com2wPeriodically ; (R16)
|
||||
pop r19
|
||||
ldi r20, COM2W_IFACE_SIZE
|
||||
add yl, r20
|
||||
adc yh, r20
|
||||
sub yh, r20
|
||||
dec r19
|
||||
brne COM2WN_Periodically_loop
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wnLowLevelRun
|
||||
;
|
||||
|
||||
com2wnLowLevelRunOnePort:
|
||||
com2wnLowLevelRun:
|
||||
.if COM_DATA_INPUT == COM_CLK_INPUT
|
||||
; begin routine for single port
|
||||
ldi yl, LOW(com2wnIoRingBuffer)
|
||||
ldi yh, HIGH(com2wnIoRingBuffer)
|
||||
rcall RingBufferY_ReadByteGuarded ; (R17, R18, X)
|
||||
brcc com2wnLowLevelRunOnePort_ret
|
||||
brcc com2wnLowLevelRun_ret
|
||||
|
||||
lds r18, com2wnIoCurrentClockStates
|
||||
eor r18, r16 ; r18: changed bits in clk states
|
||||
@@ -35,11 +117,11 @@ com2wnLowLevelRunOnePort:
|
||||
ldi r19, COM_PORTS
|
||||
ldi yl, LOW(com2w0_iface) ; first interface
|
||||
ldi yh, HIGH(com2w0_iface)
|
||||
com2wnLowLevelRunOnePort_loop: ; loop through all interfaces
|
||||
com2wnLowLevelRun_loop: ; loop through all interfaces
|
||||
ldd r20, Y+COM2W_IFACE_OFFS_PINMASK_CLK
|
||||
mov r21, r20
|
||||
and r21, r18 ; CLK for interface changed?
|
||||
breq com2wnLowLevelRunOnePort_nextIface
|
||||
breq com2wnLowLevelRun_nextIface
|
||||
push r16
|
||||
push r18
|
||||
push r19
|
||||
@@ -48,29 +130,85 @@ com2wnLowLevelRunOnePort_loop: ; loop through all interfaces
|
||||
pop r19
|
||||
pop r18
|
||||
pop r16
|
||||
com2wnLowLevelRunOnePort_nextIface:
|
||||
adiw yh:yl, COM2W_IFACE_SIZE
|
||||
com2wnLowLevelRun_nextIface:
|
||||
ldi r20, COM2W_IFACE_SIZE
|
||||
add yl, r20
|
||||
adc yh, r20
|
||||
sub yh, r20
|
||||
dec r19
|
||||
brne com2wnLowLevelRunOnePort_loop
|
||||
brne com2wnLowLevelRun_loop
|
||||
sec
|
||||
com2wnLowLevelRunOnePort_ret:
|
||||
com2wnLowLevelRun_ret:
|
||||
ret
|
||||
; end routine for single port
|
||||
.else
|
||||
; begin routine for double port
|
||||
ldi yl, LOW(com2wnIoRingBuffer)
|
||||
ldi yh, HIGH(com2wnIoRingBuffer)
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
rcall RingBufferY_ReadByte ; (R17, R18, X)
|
||||
brcc com2wnLowLevelRun_popr15Ret
|
||||
push r16
|
||||
rcall RingBufferY_ReadByte ; (R17, R18, X)
|
||||
mov r17, r16
|
||||
pop r16
|
||||
out SREG, r15
|
||||
pop r15
|
||||
|
||||
lds r18, com2wnIoCurrentClockStates
|
||||
eor r18, r16 ; r18: changed bits in clk states
|
||||
sts com2wnIoCurrentClockStates, r16 ; store new state
|
||||
; r16=clock byte, r17=data byte, r18=clock change byte
|
||||
ldi r19, COM_PORTS
|
||||
ldi yl, LOW(com2w0_iface) ; first interface
|
||||
ldi yh, HIGH(com2w0_iface)
|
||||
com2wnLowLevelRun_loop: ; loop through all interfaces
|
||||
ldd r20, Y+COM2W_IFACE_OFFS_PINMASK_CLK
|
||||
mov r21, r20
|
||||
and r21, r18 ; CLK for interface changed?
|
||||
breq com2wnLowLevelRun_nextIface
|
||||
push r16
|
||||
push r18
|
||||
push r19
|
||||
rcall com2wnActOnClock ; (r16, r17, r18, X)
|
||||
pop r19
|
||||
pop r18
|
||||
pop r16
|
||||
com2wnLowLevelRun_nextIface:
|
||||
ldi r20, COM2W_IFACE_SIZE
|
||||
add yl, r20
|
||||
adc yh, r20
|
||||
sub yh, r20
|
||||
dec r19
|
||||
brne com2wnLowLevelRun_loop
|
||||
sec
|
||||
rjmp com2wnLowLevelRun_ret
|
||||
com2wnLowLevelRun_popr15Ret:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
clc
|
||||
com2wnLowLevelRun_ret:
|
||||
ret
|
||||
; end routine for double port
|
||||
.endif
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wPeriodically @global
|
||||
;
|
||||
; @clobbers R16, Y
|
||||
; @param Y pointer to interface data
|
||||
; @clobbers R16
|
||||
|
||||
com2wPeriodically:
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
rcall NET_Interface_Periodically
|
||||
rcall NET_Interface_Periodically ; (R16)
|
||||
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
|
||||
inc r16
|
||||
breq com2wPeriodically_end
|
||||
@@ -193,7 +331,7 @@ com2wnRunIdle_haveMsg:
|
||||
push r16
|
||||
rcall NET_Buffer_Locate ; (R17)
|
||||
adiw xh:xl, 1
|
||||
rcall com2w0SendMsg ; (R16, R17, R22, R24, R25, X)
|
||||
rcall com2wnSendMsg ; (R16, R17, R22, R24, R25, X)
|
||||
push r15
|
||||
in r15, SREG ; save SREG (no CLI, we want to save CFLAG only)
|
||||
ldi r16, COM2W_MODE_IDLE
|
||||
|
||||
@@ -20,22 +20,22 @@
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wSendMsg
|
||||
; @routine com2wnSendMsg
|
||||
;
|
||||
; @param X pointer to bytes to send
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @return CFLAG set if message sent, cleared otherwise
|
||||
; @clobbers R16, R18 (R20, R22, R24, R25, X)
|
||||
|
||||
com2wSendMsg:
|
||||
com2wnSendMsg:
|
||||
ldi r20, 6 ; wait for about 60us for clock low
|
||||
rcall com2wWaitForClockLowMulti10Us ; (R17, R20, R22)
|
||||
brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy
|
||||
brcs com2wnSendMsg_busy ; CLK got low while waiting, so line is busy
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli ; atomic disable irq and set CLK low
|
||||
rcall com2wDisableClkIrq ; (none)
|
||||
rcall com2wClkSetLow ; reserve bus (none)
|
||||
rcall com2wnDisableClkIrq ; (none)
|
||||
rcall com2wnClkSetLow ; reserve bus (none)
|
||||
out SREG, r15
|
||||
pop r15
|
||||
adiw xh:xl, NETMSG_OFFS_MSGLEN
|
||||
@@ -44,17 +44,17 @@ com2wSendMsg:
|
||||
inc r18 ; adjust for DESTADDR
|
||||
inc r18 ; adjust for MSGLEN
|
||||
inc r18 ; adjust for CRCBYTE
|
||||
rcall com2wWaitTime1 ; longer wait period (R22)
|
||||
rcall com2wSendBytes ; (r16, r17, r18, r22, X)
|
||||
rcall com2wnWaitTime1 ; longer wait period (R22)
|
||||
rcall com2wnSendBytes ; (r16, r17, r18, r22, X)
|
||||
rcall com2wClkSetHigh ; make sure bus is released
|
||||
rcall com2wDataSetHigh
|
||||
rcall com2wnDataSetHigh
|
||||
|
||||
rcall com2wEnableClkIrq ; (none)
|
||||
rcall com2wnEnableClkIrq ; (none)
|
||||
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
sec
|
||||
ret
|
||||
com2wSendMsg_busy:
|
||||
com2wnSendMsg_busy:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
clc
|
||||
@@ -64,68 +64,68 @@ com2wSendMsg_busy:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wSendBytes
|
||||
; @routine com2wnSendBytes
|
||||
;
|
||||
; @param R18 number of bytes to send
|
||||
; @param X pointer to bytes to send
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers: r16, r18, X (r17, r22)
|
||||
|
||||
com2wSendBytes:
|
||||
com2wSendBytes_loop:
|
||||
rcall com2wClkSetLow ; (none)
|
||||
rcall com2wWaitTime1 ; longer wait period (R22)
|
||||
com2wnSendBytes:
|
||||
com2wnSendBytes_loop:
|
||||
rcall com2wnClkSetLow ; (none)
|
||||
rcall com2wnWaitTime1 ; longer wait period (R22)
|
||||
ld r16, X+
|
||||
rcall com2wSendByte ; (R16, R17, R22)
|
||||
rcall com2wnSendByte ; (R16, R17, R22)
|
||||
dec r18
|
||||
brne com2wSendBytes_loop
|
||||
brne com2wnSendBytes_loop
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wSendByte
|
||||
; @routine com2wnSendByte
|
||||
;
|
||||
; @param R16 byte to send
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers r16, r17 (r22)
|
||||
|
||||
com2wSendByte:
|
||||
com2wnSendByte:
|
||||
ldi r17, 8
|
||||
com2wSendByte_loop:
|
||||
rcall com2wClkSetLow
|
||||
rcall com2wWaitTime1 ; longer wait period (R22)
|
||||
com2wnSendByte_loop:
|
||||
rcall com2wnClkSetLow
|
||||
rcall com2wnWaitTime1 ; longer wait period (R22)
|
||||
lsr r16
|
||||
brcs com2wSendByte_send1
|
||||
rcall com2wDataSetLow
|
||||
rjmp com2wSendByte_sent
|
||||
com2wSendByte_send1:
|
||||
rcall com2wDataSetHigh
|
||||
com2wSendByte_sent:
|
||||
rcall com2wWaitTime2 ; shorter wait period (R22)
|
||||
brcs com2wnSendByte_send1
|
||||
rcall com2wnDataSetLow
|
||||
rjmp com2wnSendByte_sent
|
||||
com2wnSendByte_send1:
|
||||
rcall com2wnDataSetHigh
|
||||
com2wnSendByte_sent:
|
||||
rcall com2wnWaitTime2 ; shorter wait period (R22)
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli ; ensure time period by disabling irqs
|
||||
rcall com2wClkSetHigh
|
||||
rcall com2wWaitTime1 ; longer wait period (R22)
|
||||
rcall com2wnWaitTime1 ; longer wait period (R22)
|
||||
out SREG, r15
|
||||
pop r15
|
||||
dec r17
|
||||
brne com2wSendByte_loop
|
||||
brne com2wnSendByte_loop
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wWaitTime1
|
||||
; @routine com2wnWaitTime1
|
||||
;
|
||||
; waits for longer period (e.g. 30ns)
|
||||
;
|
||||
; @clobbers R22
|
||||
|
||||
com2wWaitTime1:
|
||||
com2wnWaitTime1:
|
||||
Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET)
|
||||
ret
|
||||
; @end
|
||||
@@ -133,13 +133,13 @@ com2wWaitTime1:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2wWaitTime2
|
||||
; @routine com2wnWaitTime2
|
||||
;
|
||||
; waits for shorter period (e.g. 10ns)
|
||||
;
|
||||
; @clobbers R22
|
||||
|
||||
com2wWaitTime2:
|
||||
com2wnWaitTime2:
|
||||
Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET)
|
||||
ret
|
||||
; @end
|
||||
|
||||
@@ -29,22 +29,44 @@
|
||||
; @clobbers: r16, r20, r22
|
||||
|
||||
com2wWaitForClockHighMulti10Us:
|
||||
.if clock == 8000000
|
||||
add r20, r20 ; *2
|
||||
add r20, r20 ; *4
|
||||
add r20, r20 ; *8
|
||||
.endif
|
||||
.elif clock == 1000000
|
||||
; nothing to do
|
||||
.if clock > 1000000
|
||||
; begin version for > 1000000 Hz
|
||||
ldi r20, LOW(clock/1000000)
|
||||
ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2
|
||||
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
|
||||
breq 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
|
||||
ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2
|
||||
com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop
|
||||
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
|
||||
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
|
||||
@@ -53,12 +75,14 @@ com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop
|
||||
nop ; +1
|
||||
|
||||
dec r20 ; +1
|
||||
brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE
|
||||
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
|
||||
|
||||
|
||||
@@ -68,22 +92,44 @@ com2wWaitForClockHighMulti10Us_stateReached:
|
||||
;
|
||||
; Wait for low CLK
|
||||
;
|
||||
; @param R20 multiple of 10us to wait (e.g. "2" for "20" us, max: 32)
|
||||
; @param R20 multiple of 10us to wait (e.g. "2" for "20" us)
|
||||
; @return CFLAG set if okay (state reached), cleared on error
|
||||
; @clobbers: r16, r20, r22
|
||||
|
||||
com2wWaitForClockLowMulti10Us:
|
||||
.if clock == 8000000
|
||||
add r20, r20 ; *2
|
||||
add r20, r20 ; *4
|
||||
add r20, r20 ; *8
|
||||
.endif
|
||||
.elif clock == 1000000
|
||||
; nothing to do
|
||||
.if clock > 1000000
|
||||
; begin version for > 1000000 Hz
|
||||
ldi r20, LOW(clock/1000000)
|
||||
ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2
|
||||
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
|
||||
ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2
|
||||
com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop
|
||||
inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port)
|
||||
@@ -103,6 +149,8 @@ com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop
|
||||
com2wWaitForClockLowMulti10Us_stateReached:
|
||||
sec ; +1
|
||||
ret ; +4
|
||||
; end version for 1000000 Hz
|
||||
.endif
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user