- move IRQ control to main code (only the main code knows exactly which combination of pins is used for com2) - split one big module into multiple smaller files (easier to maintain)
235 lines
6.3 KiB
NASM
235 lines
6.3 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2026 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. *
|
|
; ***************************************************************************
|
|
|
|
#ifndef AVR_MODULES_COM2W2_MAIN_H
|
|
#define AVR_MODULES_COM2W2_MAIN_H
|
|
|
|
|
|
.cseg
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine COM2W2_Init
|
|
;
|
|
; @clobbers
|
|
|
|
COM2W2_Init:
|
|
ldi yl, LOW(com2w2_iface)
|
|
ldi yh, HIGH(com2w2_iface)
|
|
rcall NET_Interface_Init ; (R16, R17, X)
|
|
|
|
; setup CLK line (as input, disable internal pull-up resistor)
|
|
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
|
|
.ifdef COM_CLK_PUE
|
|
inr r16, COM_CLK_PUE
|
|
cbr r16, (1<<COM_CLK_PIN) ; disable pullup on CLK
|
|
outr COM_CLK_PUE, r16
|
|
.else
|
|
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
|
|
.endif
|
|
|
|
; setup DATA line (as input, disable internal pull-up resistor)
|
|
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
|
|
.ifdef COM_DATA_PUE
|
|
inr r16, COM_DATA_PUE
|
|
cbr r16, (1<<COM_DATA_PIN) ; disable pullup on DATA
|
|
outr COM_DATA_PUE, r16
|
|
.else
|
|
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
|
|
.endif
|
|
|
|
.ifdef COM_SETUPIRQ_FN
|
|
bigcall COM_SETUPIRQ_FN
|
|
.endif
|
|
|
|
; setup pin-change interrupt for CLK
|
|
rcall com2w2EnableClkIrq
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine COM2W2_Every100ms @global
|
|
;
|
|
; @clobbers R16, Y
|
|
|
|
COM2W2_Every100ms:
|
|
ldi yl, LOW(com2w2_iface)
|
|
ldi yh, HIGH(com2w2_iface)
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
rcall NET_Interface_Periodically ; (R16)
|
|
out SREG, r15
|
|
pop r15
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine COM2W2_Run @global
|
|
;
|
|
; @clobbers (R16, R17, R18, R20, R22, R24, R25, X)
|
|
|
|
COM2W2_Run:
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
ldi yl, LOW(com2w2_iface)
|
|
ldi yh, HIGH(com2w2_iface)
|
|
rcall com2w2SendNextPkg ; (R16, R17, R18, R20, R22, R24, R25, X)
|
|
brcs COM2W2_Run_ok
|
|
pop r15
|
|
clc
|
|
rjmp COM2W2_Run_ret
|
|
COM2W2_Run_ok:
|
|
pop r15
|
|
sec
|
|
COM2W2_Run_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2w2ReceiveNextPkg
|
|
;
|
|
; Receive packet.
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers R16, R17, R18, R19, R20, R22, R24, R25, X
|
|
|
|
com2w2ReceiveNextPkg:
|
|
mov xl, yl
|
|
mov xh, yh
|
|
adiw xh:xl, COM2W2_IFACE_OFFS_BUFFER
|
|
ldi r19, COM2W2_BUFFER_SIZE
|
|
rcall com2w2RecvMsg ; (r16, r17, r18, r19, r20, r22, r24, r25, X)
|
|
brcc com2w2ReceiveNextPkg_end
|
|
|
|
mov xl, yl
|
|
mov xh, yh
|
|
adiw xh:xl, COM2W2_IFACE_OFFS_BUFFER
|
|
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
|
brcc com2w2ReceiveNextPkg_eCrc
|
|
|
|
#ifndef COM_ACCEPT_ALL_DEST
|
|
; check destination addr
|
|
mov xl, yl
|
|
mov xh, yh
|
|
adiw xh:xl, COM2W2_IFACE_OFFS_BUFFER
|
|
adiw xh:xl, NETMSG_OFFS_DESTADDR
|
|
ld r16, X ; read destination address
|
|
cpi r16, 0xff
|
|
breq com2w2ReceiveNextPkg_forMe
|
|
ldd r17, Y+NET_IFACE_OFFS_ADDRESS
|
|
cp r16, r17
|
|
breq com2w2ReceiveNextPkg_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 com2w2ReceiveNextPkg_end
|
|
com2w2ReceiveNextPkg_forMe:
|
|
#endif
|
|
|
|
; msg received, alloc buffer for it
|
|
rcall NET_Buffer_Alloc ; R16=buffer num (R16, R17, X)
|
|
brcs com2w2ReceiveNextPkg_gotBuffer
|
|
; out of memory
|
|
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
rjmp com2w2ReceiveNextPkg_end
|
|
|
|
; copy received message into allocated buffer
|
|
com2w2ReceiveNextPkg_gotBuffer:
|
|
mov r19, r16 ; save buffer num
|
|
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
|
|
mov r16, r19 ; restore buffer num
|
|
push zl
|
|
push zh
|
|
mov zl, yl
|
|
mov zh, yh
|
|
adiw zh:zl, COM2W2_IFACE_OFFS_BUFFER ; Z=SRC
|
|
adiw xh:xl, 1 ; X=DEST
|
|
ldd r18, Z+NETMSG_OFFS_MSGLEN
|
|
inc r18
|
|
inc r18
|
|
inc r18
|
|
com2w2ReceiveNextPkg_copyLoop:
|
|
ld r17, Z+
|
|
st X+, r17
|
|
dec r18
|
|
brne com2w2ReceiveNextPkg_copyLoop
|
|
pop zh
|
|
pop zl
|
|
|
|
; add to incoming msg pool
|
|
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
|
|
brcc com2w2ReceiveNextPkg_eMissed
|
|
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
#ifdef LED1_NETWORK_ACTIVITY
|
|
bigcall LED1_SetActivityTiming
|
|
#endif
|
|
rjmp com2w2ReceiveNextPkg_end
|
|
com2w2ReceiveNextPkg_eCrc:
|
|
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
rjmp com2w2ReceiveNextPkg_end
|
|
com2w2ReceiveNextPkg_eMissed:
|
|
push r16
|
|
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
pop r16
|
|
; fall-through to release buffer
|
|
com2w2ReceiveNextPkg_relBuffer:
|
|
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
|
com2w2ReceiveNextPkg_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2w2SendNextPkg @global
|
|
;
|
|
; Check whether there is an outgoing message in interface data
|
|
; and send it if possible.
|
|
;
|
|
; @return CFLAG set if okay, clear on error
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers (R16, R17, R18, R20, R22, R24, R25, X)
|
|
|
|
com2w2SendNextPkg:
|
|
rcall NET_Interface_PeekNextOutgoingMsgNum ; (R17, R18, X)
|
|
brcc com2w2SendNextPkg_end
|
|
rcall NET_Buffer_Locate ; get pointer to buffer (R17)
|
|
brcc com2w2SendNextPkg_end
|
|
adiw xh:xl, 1 ; skip buffer header
|
|
rcall com2w2SendMsg ; (R16, R18, R20, R22, R24, R25, X)
|
|
brcc com2w2SendNextPkg_end
|
|
rcall NET_Interface_GetNextOutgoingMsgNum ; remove from stack (R17, R18, X)
|
|
rcall NET_Buffer_ReleaseByNum ; release buffer (R16, X)
|
|
sec
|
|
com2w2SendNextPkg_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|