avr: added com2w2 (slightly improved version of com2w).
- 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)
This commit is contained in:
234
avr/modules/com2w2/main.asm
Normal file
234
avr/modules/com2w2/main.asm
Normal file
@@ -0,0 +1,234 @@
|
||||
; ***************************************************************************
|
||||
; 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
|
||||
|
||||
Reference in New Issue
Block a user