1230 lines
30 KiB
NASM
1230 lines
30 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2025 by Martin Preuss
|
|
; email : martin@libchipcard.de
|
|
;
|
|
; ***************************************************************************
|
|
; * This file is part of the project "AqHome". *
|
|
; * Please see toplevel file COPYING of that project for license details. *
|
|
; ***************************************************************************
|
|
|
|
; work in progress!
|
|
|
|
#ifndef AVR_MODULES_COM2W_COM2WI_H
|
|
#define AVR_MODULES_COM2W_COM2WI_H
|
|
|
|
|
|
.equ COM2WI_BUFFER_SIZE = NET_BUFFERS_SIZE-1
|
|
|
|
.equ COM2WI_R_MAX_WAIT_HI_TIME = 100 ; max 1ms
|
|
.equ COM2WI_S_MAX_WAIT_HI_TIME = 100 ; max 1ms
|
|
.equ COM2WI_S_MAX_WAIT_LO_TIME = 100 ; max 1ms
|
|
|
|
|
|
.equ COM2WI_W_MAX_WAIT_BUSFREE = 100 ; max 1ms
|
|
|
|
.equ COM2WI_STATETIMER_W_BYTEHOLDCLOCKLOW = 2 ; 20 us
|
|
.equ COM2WI_STATETIMER_W_BITHOLDCLOCKLOW = 2 ; 20 us
|
|
.equ COM2WI_STATETIMER_W_BITSETDATA = 2 ; 20 us
|
|
.equ COM2WI_STATETIMER_W_BITHOLDCLOCKHIGH = 2 ; 20 us
|
|
.equ COM2WI_STATETIMER_R_WAITFORCLOCKHIGH = 100 ; 1 ms
|
|
.equ COM2WI_STATETIMER_R_WAITFORCLOCKLOW = 100 ; 1 ms
|
|
.equ COM2WI_STATETIMER_S_WAITFORCLOCKLOW = 100 ; 1 ms
|
|
|
|
.equ COM2WI_STATE_IDLE = 0
|
|
|
|
.equ COM2WI_STATE_W_MSGWAITBUSFREE = 1
|
|
.equ COM2WI_STATE_W_BYTEHOLDCLOCKLOW = 2
|
|
.equ COM2WI_STATE_W_BITHOLDCLOCKLOW = 3
|
|
.equ COM2WI_STATE_W_BITSETDATA = 4
|
|
.equ COM2WI_STATE_W_BITHOLDCLOCKHIGH = 5
|
|
.equ COM2WI_STATE_W_MSGSENT = 6
|
|
|
|
.equ COM2WI_STATE_R_WAITFORCLOCKHIGH = 7
|
|
.equ COM2WI_STATE_R_WAITFORCLOCKLOW = 8
|
|
.equ COM2WI_STATE_R_MSGRECVD = 9
|
|
|
|
.equ COM2WI_STATE_S_WAITFORCLOCKLOW = 10
|
|
.equ COM2WI_STATE_S_WAITFORCLOCKHIGH = 11
|
|
|
|
.equ COM2WI_STATE_COUNT = 12
|
|
|
|
|
|
|
|
.equ COM2WI_IFACE_OFFS_BEGIN = NET_IFACE_SIZE
|
|
.equ COM2WI_IFACE_OFFS_STATE = COM2WI_IFACE_OFFS_BEGIN+0
|
|
.equ COM2WI_IFACE_OFFS_STATETIMER = COM2WI_IFACE_OFFS_BEGIN+1
|
|
.equ COM2WI_IFACE_OFFS_STATECOUNTER = COM2WI_IFACE_OFFS_BEGIN+2
|
|
.equ COM2WI_IFACE_OFFS_PINMASK_CLK = COM2WI_IFACE_OFFS_BEGIN+3
|
|
.equ COM2WI_IFACE_OFFS_PINMASK_DATA = COM2WI_IFACE_OFFS_BEGIN+4
|
|
.equ COM2WI_IFACE_OFFS_BITCOUNTER = COM2WI_IFACE_OFFS_BEGIN+5
|
|
.equ COM2WI_IFACE_OFFS_CURRBYTE = COM2WI_IFACE_OFFS_BEGIN+6
|
|
.equ COM2WI_IFACE_OFFS_BUFPOS_LOW = COM2WI_IFACE_OFFS_BEGIN+7
|
|
.equ COM2WI_IFACE_OFFS_BUFPOS_HIGH = COM2WI_IFACE_OFFS_BEGIN+8
|
|
.equ COM2WI_IFACE_OFFS_BUFUSED = COM2WI_IFACE_OFFS_BEGIN+9
|
|
.equ COM2WI_IFACE_OFFS_BUFLEFT = COM2WI_IFACE_OFFS_BEGIN+10
|
|
.equ COM2WI_IFACE_OFFS_BUFFER = COM2WI_IFACE_OFFS_BEGIN+11
|
|
.equ COM2WI_IFACE_SIZE = COM2WI_IFACE_OFFS_BUFFER+COM2WI_BUFFER_SIZE
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @macro mCOM2WI_INIT
|
|
;
|
|
; @param @0 interface number (beginning with 0)
|
|
|
|
.macro mCOM2WI_INIT
|
|
ldi yl, LOW(com2wi@0_iface)
|
|
ldi yh, HIGH(com2wi@0_iface)
|
|
|
|
mov xl, yl
|
|
mov xh, yh
|
|
ldi r17, COM2WI_IFACE_SIZE
|
|
clr r16
|
|
rcall Utils_FillSram ; (R17, X)
|
|
|
|
rcall NET_Interface_Init ; (R16, R17, X)
|
|
|
|
ldi r16, @0 +1
|
|
std Y+NET_IFACE_OFFS_IFACENUM, r16
|
|
|
|
ldi r16, COM_MASK_CLK@0
|
|
std Y+COM2WI_IFACE_OFFS_PINMASK_CLK, r16
|
|
ldi r16, COM_MASK_DATA@0
|
|
std Y+COM2WI_IFACE_OFFS_PINMASK_DATA, r16
|
|
; ldi r16, COM_MASK_IRQ@0
|
|
; std Y+COM2WI_IFACE_OFFS_PINMASK_IRQ, r16
|
|
rcall com2wiInit
|
|
.endmacro
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
.dseg
|
|
|
|
|
|
|
|
.if COM_PORTS >0
|
|
com2wi0_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
.if COM_PORTS >1
|
|
com2wi1_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
.if COM_PORTS >2
|
|
com2wi2_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
.if COM_PORTS >3
|
|
com2wi3_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
.if COM_PORTS >4
|
|
com2wi4_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
.if COM_PORTS >5
|
|
com2wi5_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
.if COM_PORTS >6
|
|
com2wi6_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
.if COM_PORTS >7
|
|
com2wi7_iface: .byte COM2WI_IFACE_SIZE
|
|
.endif
|
|
|
|
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine COM2WI_Init
|
|
|
|
COM2WI_Init:
|
|
.if COM_PORTS >0
|
|
mCOM2WI_INIT 0
|
|
.endif
|
|
|
|
.if COM_PORTS >1
|
|
mCOM2WI_INIT 1
|
|
.endif
|
|
|
|
.if COM_PORTS >2
|
|
mCOM2WI_INIT 2
|
|
.endif
|
|
|
|
.if COM_PORTS >3
|
|
mCOM2WI_INIT 3
|
|
.endif
|
|
|
|
.if COM_PORTS >4
|
|
mCOM2WI_INIT 4
|
|
.endif
|
|
|
|
.if COM_PORTS >5
|
|
mCOM2WI_INIT 5
|
|
.endif
|
|
|
|
.if COM_PORTS >6
|
|
mCOM2WI_INIT 6
|
|
.endif
|
|
|
|
.if COM_PORTS >7
|
|
mCOM2WI_INIT 7
|
|
.endif
|
|
|
|
rcall com2wiSetupTimer1
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine COM2WI_Timer1Isr @global @isr
|
|
;
|
|
; ISR for timer1
|
|
;
|
|
; @clobbers: none
|
|
|
|
COM2WI_Timer1Isr:
|
|
push r15
|
|
in r15, SREG
|
|
push r1
|
|
push r2
|
|
inr r1, COM_CLK_INPUT
|
|
inr r2, COM_DATA_INPUT
|
|
push r16
|
|
push r17
|
|
push r18
|
|
push yl
|
|
push yh
|
|
push zl
|
|
push zh
|
|
rcall COM2WI_HandleTimerIrq ; (r16, r17, r18, Y, Z)
|
|
pop zh
|
|
pop zl
|
|
pop yh
|
|
pop yl
|
|
pop r18
|
|
pop r17
|
|
pop r16
|
|
pop r2
|
|
pop r1
|
|
out SREG, r15
|
|
pop r15
|
|
reti
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine COM2WI_Run
|
|
|
|
COM2WI_Run:
|
|
ldi yl, LOW(com2wi0_iface)
|
|
ldi yh, HIGH(com2wi0_iface)
|
|
ldi r18, COM_PORTS
|
|
clr r19
|
|
COM2WI_Run_loop:
|
|
push r18
|
|
push r19
|
|
rcall com2wiRun
|
|
pop r19
|
|
pop r18
|
|
sbci r19, 0
|
|
ldi r16, COM2WI_IFACE_SIZE
|
|
add yl, r16
|
|
adc yh, r16
|
|
sub yh, r16
|
|
dec r18
|
|
brne COM2WI_Run_loop
|
|
|
|
; check for repeat request
|
|
tst r19
|
|
clc
|
|
breq COM2WI_Run_end
|
|
sec
|
|
COM2WI_Run_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine COM2WI_HandleTimerIrq
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers R16, R17, R18, Y, Z
|
|
|
|
COM2WI_HandleTimerIrq:
|
|
ldi yl, LOW(com2wi0_iface)
|
|
ldi yh, HIGH(com2wi0_iface)
|
|
ldi r18, COM_PORTS
|
|
COM2WI_HandleTimerIrq_loop:
|
|
push r18
|
|
rcall com2wiHandleIrq ; R16, R17, R18, Z
|
|
pop r18
|
|
ldi r16, COM2WI_IFACE_SIZE
|
|
add yl, r16
|
|
adc yh, r16
|
|
sub yh, r16
|
|
dec r18
|
|
brne COM2WI_HandleTimerIrq_loop
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiInit
|
|
|
|
com2wiInit:
|
|
rcall com2wiSetupLines
|
|
|
|
ldi r16, COM2WI_STATE_IDLE
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiSetupLines
|
|
|
|
com2wiSetupLines:
|
|
; setup CLK line (as input, disable internal pull-up resistor)
|
|
.ifdef COM_CLK_PUE
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
com r16
|
|
inr r17, COM_CLK_PUE
|
|
and r17, r16
|
|
outr COM_CLK_PUE, r17
|
|
.endif
|
|
rcall com2wiClkSetHigh
|
|
|
|
; setup DATA line (as input, disable internal pull-up resistor)
|
|
.ifdef COM_DATA_PUE
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_PINMASK_DATA
|
|
com r16
|
|
inr r17, COM_DATA_PUE
|
|
and r17, r16
|
|
outr COM_DATA_PUE, r17
|
|
.endif
|
|
rcall com2wiDataSetHigh
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiSetupTimer1
|
|
;
|
|
; setup timer for IRQ every 20us
|
|
|
|
com2wiSetupTimer1:
|
|
; CTC mode, no prescaler, OCR1A=100 (every 20us at 20MHz)
|
|
; WGM13=0, WGM12=1, WGM11=0, WGM10=0
|
|
ldi r16, 0
|
|
outr TCCR1A, r16 ; WGM11=0, WGM10=0
|
|
ldi r16, (0<<CS12) | (0<<CS11) | (1<<CS10) | (0<<WGM13) | (1<<WGM12)
|
|
outr TCCR1B, r16
|
|
|
|
clr r17 HIGH(200)
|
|
ldi r16, LOW(200)
|
|
outr OCR1AH, r17
|
|
outr OCR1AL, r16
|
|
|
|
ldi r16, (1<<OCF1A) ; clear pending interrupts
|
|
outr TIFR1, r16
|
|
|
|
inr r16, TIMSK1
|
|
sbr r16, (1<<OCIE1A) ; Timer/Counter1 Output Compare Match A Interrupt Enable
|
|
outr TIMSK1, r16
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiClkSetHigh
|
|
;
|
|
; @clobbers none
|
|
|
|
com2wiClkSetHigh:
|
|
push r16
|
|
push r17
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
; clear bit in io reg (AND with complement)
|
|
com r16
|
|
inr r17, COM_CLK_DDR
|
|
and r17, r16
|
|
outr COM_CLK_DDR, r17 ; make pin input
|
|
.ifndef COM_CLK_PUE
|
|
inr r17, COM_CLK_OUTPUT
|
|
and r17, r16 ; disable pullup
|
|
outr COM_CLK_OUTPUT, r17
|
|
.endif
|
|
pop r17
|
|
pop r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiClkSetLow
|
|
;
|
|
; @clobbers none
|
|
|
|
com2wiClkSetLow:
|
|
push r16
|
|
push r17
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
; set bit in io reg
|
|
inr r17, COM_CLK_DDR
|
|
or r17, r16
|
|
outr COM_CLK_DDR, r17 ; make pin output
|
|
|
|
com r16
|
|
inr r17, COM_CLK_OUTPUT
|
|
and r17, r16
|
|
outr COM_CLK_OUTPUT, r17 ; set pin low
|
|
|
|
pop r17
|
|
pop r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiDataSetHigh
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers none
|
|
|
|
com2wiDataSetHigh:
|
|
push r16
|
|
push r17
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_PINMASK_DATA
|
|
; clear bit in io reg (AND with complement)
|
|
com r16
|
|
inr r17, COM_DATA_DDR
|
|
and r17, r16
|
|
outr COM_DATA_DDR, r17 ; make pin input
|
|
.ifndef COM_DATA_PUE
|
|
inr r17, COM_DATA_OUTPUT
|
|
and r17, r16 ; disable pullup
|
|
outr COM_DATA_OUTPUT, r17
|
|
.endif
|
|
pop r17
|
|
pop r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiDataSetLow
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers none
|
|
|
|
com2wiDataSetLow:
|
|
push r16
|
|
push r17
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_PINMASK_DATA
|
|
; set bit in io reg
|
|
inr r17, COM_DATA_DDR
|
|
or r17, r16
|
|
outr COM_DATA_DDR, r17 ; make pin output
|
|
|
|
com r16
|
|
inr r17, COM_DATA_OUTPUT
|
|
and r17, r16
|
|
outr COM_DATA_OUTPUT, r17 ; set pin low
|
|
|
|
pop r17
|
|
pop r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiHandleIrq
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers R16, R17, R18, Z
|
|
|
|
com2wiHandleIrq:
|
|
; dec state timer
|
|
ldd r17, Y+COM2WI_IFACE_OFFS_STATETIMER
|
|
tst r17
|
|
breq com2wiHandleIrq_jmp
|
|
dec r17
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r17
|
|
; jump
|
|
com2wiHandleIrq_jmp:
|
|
ldi zl, LOW(com2wiIrqJumpTable)
|
|
ldi zh, HIGH(com2wiIrqJumpTable)
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_STATE
|
|
cpi r16, COM2WI_STATE_COUNT
|
|
brcc com2wiHandleIrq_ret
|
|
add zl, r16
|
|
adc zh, r16
|
|
sub zh, r16
|
|
ijmp
|
|
com2wiHandleIrq_ret:
|
|
ret
|
|
com2wiIrqJumpTable:
|
|
rjmp com2wiIrqStateIdle ; 0: COM2WI_STATE_IDLE (r16, r18)
|
|
rjmp com2wiIrqStateWMsgWaitBusFree ; 1: COM2WI_STATE_W_MSGWAITBUSFREE (r16, r18)
|
|
rjmp com2wiIrqStateWByteHoldClockLow ; 2: COM2WI_STATE_W_BYTEHOLDCLOCKLOW (r16)
|
|
rjmp com2wiIrqStateWBitHoldClockLow ; 3: COM2WI_STATE_W_BITHOLDCLOCKLOW (r16)
|
|
rjmp com2wiIrqStateWBitSetData ; 4: COM2WI_STATE_W_BITSETDATA (r16)
|
|
rjmp com2wiIrqStateWBitHoldClockHigh ; 5: COM2WI_STATE_W_BITHOLDCLOCKHIGH (r16)
|
|
ret ; 6: COM2WI_STATE_W_MSGSENT
|
|
rjmp com2wiIrqStateRWaitForClockHigh ; 7: COM2WI_STATE_R_WAITFORCLOCKHIGH
|
|
rjmp com2wiIrqStateRWaitForClockLow ; 8: COM2WI_STATE_R_WAITFORCLOCKLOW
|
|
ret ; 9: COM2WI_STATE_R_MSGRECVD
|
|
rjmp com2wiIrqStateSWaitForClockLow ; 10: COM2WI_STATE_S_WAITFORCLOCKLOW
|
|
rjmp com2wiIrqStateSWaitForClockHigh ; 11: COM2WI_STATE_S_WAITFORCLOCKHIGH
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateIdle
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16, r18
|
|
|
|
com2wiIrqStateIdle:
|
|
mov r16, r1
|
|
; inr r16, COM_CLK_INPUT
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
and r16, r18
|
|
brne com2wiIrqStateIdle_ret
|
|
; CLK is low, start receiving
|
|
push xl
|
|
push xh
|
|
mov xh, yh
|
|
mov xl, yl
|
|
adiw xh:xl, COM2WI_IFACE_OFFS_BUFFER
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_LOW, xl
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_HIGH, xh
|
|
ldi r16, COM2WI_BUFFER_SIZE
|
|
std Y+COM2WI_IFACE_OFFS_BUFLEFT, r16
|
|
clr r16
|
|
std Y+COM2WI_IFACE_OFFS_BUFUSED, r16
|
|
std Y+COM2WI_IFACE_OFFS_BITCOUNTER, r16
|
|
pop xh
|
|
pop xl
|
|
rjmp com2wiEnterStateRWaitForClockHigh
|
|
com2wiIrqStateIdle_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateWMsgWaitBusFree
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16, r18
|
|
|
|
com2wiIrqStateWMsgWaitBusFree:
|
|
inr r16, COM_CLK_INPUT
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
and r16, r18
|
|
brne com2wiIrqStateWMsgWaitBusFree_isHi
|
|
; CLK line is low, restart wait counter
|
|
ldi r16, COM2WI_W_MAX_WAIT_BUSFREE
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ret
|
|
com2wiIrqStateWMsgWaitBusFree_isHi:
|
|
tst r17
|
|
brne com2wiIrqStateWMsgWaitBusFree_ret
|
|
; CLK still high, time's up, start transmitting
|
|
rjmp com2wiEnterStateWByteHoldClockLow
|
|
com2wiIrqStateWMsgWaitBusFree_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateWMsgWaitBusFree
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16
|
|
|
|
com2wiIrqStateWByteHoldClockLow:
|
|
tst r17
|
|
brne com2wiIrqStateWByteHoldClockLow_ret
|
|
rjmp com2wiEnterStateWBitHoldClockLow ; (r16)
|
|
com2wiIrqStateWByteHoldClockLow_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateWMsgWaitBusFree
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16
|
|
|
|
com2wiIrqStateWBitHoldClockLow:
|
|
tst r17
|
|
brne com2wiIrqStateWBitHoldClockLow_ret
|
|
rjmp com2wiEnterStateWBitSetData ; (r16)
|
|
com2wiIrqStateWBitHoldClockLow_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateWBitSetData
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16
|
|
|
|
com2wiIrqStateWBitSetData:
|
|
tst r17
|
|
brne com2wiIrqStateWBitSetData_ret
|
|
rjmp com2wiEnterStateWBitHoldClockHigh
|
|
com2wiIrqStateWBitSetData_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateWBitHoldClockHigh
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16
|
|
|
|
com2wiIrqStateWBitHoldClockHigh:
|
|
tst r17
|
|
brne com2wiIrqStateWBitHoldClockHigh_ret
|
|
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_BITCOUNTER
|
|
cpi r16, 8
|
|
breq com2wiIrqStateWBitHoldClockHigh_byteFull
|
|
rjmp com2wiEnterStateWBitHoldClockLow ; (r16)
|
|
com2wiIrqStateWBitHoldClockHigh_byteFull:
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_BUFLEFT
|
|
tst r16
|
|
brne com2wiIrqStateWBitHoldClockHigh_nextByte
|
|
rjmp com2wiEnterStateWMsgSent ; (r16)
|
|
com2wiIrqStateWBitHoldClockHigh_nextByte:
|
|
rjmp com2wiEnterStateWByteHoldClockLow
|
|
com2wiIrqStateWBitHoldClockHigh_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateRWaitForClockHigh
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16
|
|
|
|
com2wiIrqStateRWaitForClockHigh:
|
|
mov r16, r1
|
|
; inr r16, COM_CLK_INPUT
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
and r16, r18
|
|
brne com2wiIrqStateRWaitForClockHigh_isHi
|
|
tst r17
|
|
brne com2wiIrqStateRWaitForClockHigh_ret
|
|
; time's up, enter skipping mode
|
|
rjmp com2wiEnterStateSWaitForClockHigh
|
|
com2wiIrqStateRWaitForClockHigh_isHi:
|
|
mov r16, r2
|
|
; inr r16, COM_DATA_INPUT
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_PINMASK_DATA
|
|
and r16, r18
|
|
clc
|
|
breq com2wiIrqStateRWaitForClockHigh_shiftIn
|
|
sec
|
|
com2wiIrqStateRWaitForClockHigh_shiftIn:
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_CURRBYTE
|
|
ror r16
|
|
std Y+COM2WI_IFACE_OFFS_CURRBYTE, r16
|
|
ldd r17, Y+COM2WI_IFACE_OFFS_BITCOUNTER
|
|
inc r17
|
|
std Y+COM2WI_IFACE_OFFS_BITCOUNTER, r17
|
|
cpi r17, 8
|
|
brne com2wiIrqStateRWaitForClockHigh_waitForLo
|
|
; byte complete, store
|
|
ldd r17, Y+COM2WI_IFACE_OFFS_BUFLEFT
|
|
dec r17
|
|
std Y+COM2WI_IFACE_OFFS_BUFLEFT, r17
|
|
clr r18
|
|
std Y+COM2WI_IFACE_OFFS_BITCOUNTER, r18
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_BUFUSED
|
|
inc r18
|
|
std Y+COM2WI_IFACE_OFFS_BUFUSED, r18
|
|
push xl
|
|
push xh
|
|
ldd xl, Y+COM2WI_IFACE_OFFS_BUFPOS_LOW
|
|
ldd xh, Y+COM2WI_IFACE_OFFS_BUFPOS_HIGH
|
|
st X+, r16
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_LOW, xl
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_HIGH, xh
|
|
pop xh
|
|
pop xl
|
|
tst r17
|
|
breq com2wiIrqStateRWaitForClockHigh_msgRecvd
|
|
; check size
|
|
cpi r18, 2
|
|
brne com2wiIrqStateRWaitForClockHigh_waitForLo
|
|
inc r16 ; last byte=remainder of msg, add CRC byte
|
|
cp r17, r16
|
|
brcs com2wiIrqStateRWaitForClockHigh_badMsgSize
|
|
std Y+COM2WI_IFACE_OFFS_BUFLEFT, r16
|
|
tst r16
|
|
breq com2wiIrqStateRWaitForClockHigh_msgRecvd ; jmp if message complete
|
|
com2wiIrqStateRWaitForClockHigh_waitForLo:
|
|
rjmp com2wiEnterStateRWaitForClockLow
|
|
com2wiIrqStateRWaitForClockHigh_badMsgSize:
|
|
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
|
|
push r24
|
|
push r25
|
|
rcall NET_Interface_IncCounter16
|
|
pop r25
|
|
pop r24
|
|
rjmp com2wiEnterStateSWaitForClockHigh
|
|
com2wiIrqStateRWaitForClockHigh_msgRecvd:
|
|
rjmp com2wiEnterStateRMsgRecvd
|
|
com2wiIrqStateRWaitForClockHigh_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateRWaitForClockLow
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16
|
|
|
|
com2wiIrqStateRWaitForClockLow:
|
|
mov r16, r1
|
|
; inr r16, COM_CLK_INPUT
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
and r16, r18
|
|
breq com2wiIrqStateRWaitForClockLow_isLo
|
|
tst r17
|
|
brne com2wiIrqStateRWaitForClockLow_ret
|
|
; time's up, enter skipping mode
|
|
rjmp com2wiEnterStateSWaitForClockLow
|
|
com2wiIrqStateRWaitForClockLow_isLo:
|
|
rjmp com2wiEnterStateRWaitForClockHigh
|
|
com2wiIrqStateRWaitForClockLow_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateSWaitForClockHigh
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16
|
|
|
|
com2wiIrqStateSWaitForClockHigh:
|
|
mov r16, r1
|
|
; inr r16, COM_CLK_INPUT
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
and r16, r18
|
|
breq com2wiIrqStateSWaitForClockHigh_ret ; jmp if still low
|
|
rjmp com2wiEnterStateSWaitForClockLow
|
|
com2wiIrqStateSWaitForClockHigh_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiIrqStateSWaitForClockLow
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @param r17 current state timer
|
|
; @clobbers r16, r18
|
|
|
|
com2wiIrqStateSWaitForClockLow:
|
|
mov r16, r1
|
|
; inr r16, COM_CLK_INPUT
|
|
ldd r18, Y+COM2WI_IFACE_OFFS_PINMASK_CLK
|
|
and r16, r18
|
|
brne com2wiIrqStateSWaitForClockLow_isHi
|
|
; CLK is low again, restart loop
|
|
rjmp com2wiEnterStateSWaitForClockHigh
|
|
com2wiIrqStateSWaitForClockLow_isHi:
|
|
tst r17
|
|
brne com2wiIrqStateSWaitForClockLow_ret
|
|
; time's up, line still high, leave skipping mode
|
|
rjmp com2wiEnterStateIdle
|
|
com2wiIrqStateSWaitForClockLow_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateIdle
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateIdle:
|
|
; setup lines (make sure we don't hold the lines low)
|
|
rcall com2wiClkSetHigh ; (none)
|
|
rcall com2wiDataSetHigh ; (none)
|
|
|
|
; setup state
|
|
clr r16
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_IDLE
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateWMsgWaitBusFree
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateWMsgWaitBusFree:
|
|
; setup lines (make sure we don't hold the lines low)
|
|
rcall com2wiClkSetHigh ; (none)
|
|
rcall com2wiDataSetHigh ; (none)
|
|
|
|
; setup state
|
|
ldi r16, COM2WI_W_MAX_WAIT_BUSFREE
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_W_MSGWAITBUSFREE
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateWByteHoldClockLow
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateWByteHoldClockLow:
|
|
; setup line
|
|
rcall com2wiClkSetLow ; (none)
|
|
|
|
; setup state
|
|
ldi r16, COM2WI_STATETIMER_W_BYTEHOLDCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_W_BYTEHOLDCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
|
|
; setup current byte
|
|
push xl
|
|
push xh
|
|
ldd xl, Y+COM2WI_IFACE_OFFS_BUFPOS_LOW
|
|
ldd xh, Y+COM2WI_IFACE_OFFS_BUFPOS_HIGH
|
|
ld r16, X+
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_LOW, xl
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_HIGH, xh
|
|
pop xh
|
|
pop xl
|
|
std Y+COM2WI_IFACE_OFFS_CURRBYTE, r16
|
|
clr r16
|
|
std Y+COM2WI_IFACE_OFFS_BITCOUNTER, r16
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_BUFLEFT
|
|
dec r16
|
|
std Y+COM2WI_IFACE_OFFS_BUFLEFT, r16
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateWBitHoldClockLow
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateWBitHoldClockLow:
|
|
; setup line
|
|
rcall com2wiClkSetLow ; (none)
|
|
|
|
; setup state
|
|
ldi r16, COM2WI_STATETIMER_W_BITHOLDCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_W_BITHOLDCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateWBitSetData
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateWBitSetData:
|
|
; setup state
|
|
ldi r16, COM2WI_STATETIMER_W_BITSETDATA
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_W_BITSETDATA
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
|
|
; setup line
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_BITCOUNTER
|
|
inc r16
|
|
std Y+COM2WI_IFACE_OFFS_BITCOUNTER, r16
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_CURRBYTE
|
|
lsr r16
|
|
std Y+COM2WI_IFACE_OFFS_CURRBYTE, r16
|
|
brcc com2wiEnterStateWBitSetData_set0
|
|
rcall com2wiDataSetHigh
|
|
ret
|
|
com2wiEnterStateWBitSetData_set0:
|
|
rcall com2wiDataSetLow
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateWBitHoldClockHigh
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateWBitHoldClockHigh:
|
|
; setup line
|
|
rcall com2wiClkSetHigh ; (none)
|
|
|
|
; setup state
|
|
ldi r16, COM2WI_STATETIMER_W_BITHOLDCLOCKHIGH
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_W_BITHOLDCLOCKHIGH
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateWMsgSent
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateWMsgSent:
|
|
; setup lines
|
|
rcall com2wiClkSetHigh ; (none)
|
|
rcall com2wiDataSetHigh ; (none)
|
|
; setup state
|
|
clr r16 ; wait indefinately
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_W_MSGSENT
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateRWaitForClockHigh
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateRWaitForClockHigh:
|
|
ldi r16, COM2WI_STATETIMER_R_WAITFORCLOCKHIGH
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_R_WAITFORCLOCKHIGH
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateRWaitForClockLow
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateRWaitForClockLow:
|
|
ldi r16, COM2WI_STATETIMER_R_WAITFORCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_R_WAITFORCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateSWaitForClockHigh
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateSWaitForClockHigh:
|
|
clr r16
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_S_WAITFORCLOCKHIGH
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiEnterStateSWaitForClockLow
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16
|
|
|
|
com2wiEnterStateSWaitForClockLow:
|
|
ldi r16, COM2WI_STATETIMER_S_WAITFORCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_S_WAITFORCLOCKLOW
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
com2wiEnterStateRMsgRecvd:
|
|
; setup state
|
|
clr r16 ; wait indefinately
|
|
std Y+COM2WI_IFACE_OFFS_STATETIMER, r16
|
|
ldi r16, COM2WI_STATE_R_MSGRECVD
|
|
std Y+COM2WI_IFACE_OFFS_STATE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wiRun
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers
|
|
|
|
com2wiRun:
|
|
ldi zl, LOW(com2wiRunJumpTable)
|
|
ldi zh, HIGH(com2wiRunJumpTable)
|
|
ldd r16, Y+COM2WI_IFACE_OFFS_STATE
|
|
cpi r16, COM2WI_STATE_COUNT
|
|
brcc com2wiRun_ret
|
|
add zl, r16
|
|
adc zh, r16
|
|
sub zh, r16
|
|
ijmp
|
|
com2wiRun_ret:
|
|
ret
|
|
com2wiRunJumpTable:
|
|
rjmp com2wiRunStateIdle ; 0: COM2WI_STATE_IDLE
|
|
ret ; 1: COM2WI_STATE_W_MSGWAITBUSFREE
|
|
ret ; 2: COM2WI_STATE_W_BYTEHOLDCLOCKLOW
|
|
ret ; 3: COM2WI_STATE_W_BITHOLDCLOCKLOW
|
|
ret ; 4: COM2WI_STATE_W_BITSETDATA
|
|
ret ; 5: COM2WI_STATE_W_BITHOLDCLOCKHIGH
|
|
rjmp com2wiRunStateWMsgSent ; 6: COM2WI_STATE_W_MSGSENT
|
|
ret ; 7: COM2WI_STATE_R_WAITFORCLOCKHI
|
|
ret ; 8: COM2WI_STATE_R_WAITFORCLOCKLO
|
|
rjmp com2wiRunStateRMsgRecvd ; 9: COM2WI_STATE_R_MSGRECVD
|
|
ret ; 10: COM2WI_STATE_S_WAITFORCLOCKLO
|
|
ret ; 11: COM2WI_STATE_S_WAITFORCLOCKHI
|
|
; @end
|
|
|
|
|
|
|
|
com2wiRunStateIdle:
|
|
; look for outbound message
|
|
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
|
|
brcc com2wiRunStateIdle_ret
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
rcall NET_Buffer_Locate ; (R17)
|
|
adiw xh:xl, 1
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_LOW, xl
|
|
std Y+COM2WI_IFACE_OFFS_BUFPOS_HIGH, xh
|
|
adiw xh:xl, NETMSG_OFFS_MSGLEN
|
|
ld r16, X
|
|
subi r16, -3
|
|
std Y+COM2WI_IFACE_OFFS_BUFUSED, r16
|
|
std Y+COM2WI_IFACE_OFFS_BUFLEFT, r16
|
|
rcall com2wiEnterStateWMsgWaitBusFree ; (R16)
|
|
out SREG, r15
|
|
pop r15
|
|
com2wiRunStateIdle_ret:
|
|
clc ; no need to re-run in this loop
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
com2wiRunStateWMsgSent:
|
|
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
|
|
brcc com2wiRunStateWMsgSent_ret
|
|
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
rcall com2wiEnterStateIdle
|
|
out SREG, r15
|
|
pop r15
|
|
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
|
|
push r24
|
|
push r25
|
|
rcall NET_Interface_IncCounter16
|
|
pop r25
|
|
pop r24
|
|
rcall LedActivity_Trigger
|
|
sec ; did something
|
|
com2wiRunStateWMsgSent_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
com2wiRunStateRMsgRecvd:
|
|
mov xl, yl
|
|
mov xh, yh
|
|
adiw xh:xl, COM2WI_IFACE_OFFS_BUFFER
|
|
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
|
brcc com2wiRunStateRMsgRecvd_crcError
|
|
#ifndef COM_ACCEPT_ALL_DEST
|
|
; check destination addr
|
|
mov xl, yl
|
|
mov xh, yh
|
|
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
|
|
adiw xh:xl, NETMSG_OFFS_DESTADDR
|
|
ld r16, X ; read destination address
|
|
cpi r16, 0xff
|
|
breq com2wiRunStateRMsgRecvd_forMe
|
|
ldd r17, Y+NET_IFACE_OFFS_ADDRESS
|
|
cp r16, r17
|
|
breq com2wiRunStateRMsgRecvd_forMe
|
|
; packet not for me, but correctly received, inc counter, but don't light LED
|
|
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
rjmp com2wiRunStateRMsgRecvd_goIdle
|
|
com2wiRunStateRMsgRecvd_forMe:
|
|
#endif
|
|
|
|
; msg received, alloc buffer for it
|
|
rcall NET_Buffer_Alloc ; R16=buffer num (R16, R17, X)
|
|
brcc com2wiRunStateRMsgRecvd_noBuf
|
|
|
|
; set interface number in msg header
|
|
mov r19, r16 ; save buffer num
|
|
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
|
|
mov r16, r19 ; restore buffer num
|
|
; copy into allocated buffer
|
|
push zl
|
|
push zh
|
|
mov zl, yl
|
|
mov zh, yh
|
|
adiw zh:zl, COM2WI_IFACE_OFFS_BUFFER ; Z=SRC
|
|
adiw xh:xl, 1 ; X=DEST
|
|
ldd r18, Z+NETMSG_OFFS_MSGLEN
|
|
inc r18
|
|
inc r18
|
|
inc r18
|
|
com2wiRunStateRMsgRecvd_copyLoop:
|
|
ld r17, Z+
|
|
st X+, r17
|
|
dec r18
|
|
brne com2wiRunStateRMsgRecvd_copyLoop
|
|
pop zh
|
|
pop zl
|
|
|
|
; add to incoming msg pool
|
|
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
|
|
brcc com2wReceiveNextPkg_eMissed
|
|
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
#ifdef MODULES_LED_ACTIVITY
|
|
rcall LedActivity_Trigger ; (r16)
|
|
#endif
|
|
; fall-through to enter idle state
|
|
com2wiRunStateRMsgRecvd_goIdle:
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
rcall com2wiEnterStateIdle
|
|
out SREG, r15
|
|
pop r15
|
|
sec
|
|
rjmp com2wiRunStateRMsgRecvd_ret
|
|
com2wiRunStateRMsgRecvd_noBuf:
|
|
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
rjmp com2wiRunStateRMsgRecvd_goIdle
|
|
com2wiRunStateRMsgRecvd_crcError:
|
|
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
rjmp com2wiRunStateRMsgRecvd_goIdle
|
|
com2wReceiveNextPkg_eMissed:
|
|
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
|
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
rjmp com2wiRunStateRMsgRecvd_goIdle
|
|
com2wiRunStateRMsgRecvd_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|