243 lines
6.9 KiB
NASM
243 lines
6.9 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. *
|
|
; ***************************************************************************
|
|
|
|
#ifndef AVR_MODULES_COM2W_COM2WN_RECV_H
|
|
#define AVR_MODULES_COM2W_COM2WN_RECV_H
|
|
|
|
|
|
; WORK IN PROGRESS
|
|
|
|
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnActOnClock @global
|
|
;
|
|
; @param r16 CLK input (0 or !=0)
|
|
; @param r17 DATA input (0 or !=0)
|
|
; @param Y pointer to IFACE data
|
|
; @clobbers r16 (r17, r18, X)
|
|
|
|
com2wnActOnClock:
|
|
tst r16
|
|
brne com2wnActOnClock_clockHigh
|
|
; clock low
|
|
ldd r18, Y+COM2W_IFACE_OFFS_MODE
|
|
cpi r18, COM2W_MODE_IDLE
|
|
breq com2wnActOnClock_startReading
|
|
cpi r18, COM2W_MODE_SKIPPING
|
|
breq com2wnActOnClock_skipping
|
|
rjmp com2wnActOnClock_end
|
|
com2wnActOnClock_skipping:
|
|
; ldd r18, Y+COM2W_IFACE_OFFS_MODECOUNTER
|
|
; cpi r18, COM2W_SKIPPING_MAXMODECOUNTER
|
|
; brcc com2wnActOnClock_startReading
|
|
rjmp com2wnActOnClock_end
|
|
com2wnActOnClock_startReading:
|
|
rcall com2wnStartReading ; (r16, r17, X)
|
|
rjmp com2wnActOnClock_end
|
|
com2wnActOnClock_clockHigh:
|
|
ldd r18, Y+COM2W_IFACE_OFFS_MODE
|
|
cpi r18, COM2W_MODE_READING
|
|
brne com2wnActOnClock_end
|
|
|
|
push r20
|
|
push r22
|
|
rcall com2wnReadNextBit ; (r16, r17, r18, r20, r22)
|
|
pop r22
|
|
pop r20
|
|
|
|
com2wnActOnClock_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnReadNextBit @global
|
|
;
|
|
; @param r17 DATA input (0 or !=0)
|
|
; @clobbers r16, r17, r18, r20, r22
|
|
|
|
com2wnReadNextBit:
|
|
; ldi r20, 50 ; wait for up to 250us for clock rise
|
|
; rcall com2w0WaitForClockHighMulti5Us ; (R20, R22)
|
|
; brcc com2wnReadNextBit_end
|
|
; clock is high now, read bit
|
|
; reset read timer (for leaving skipping mode)
|
|
clr r16
|
|
std Y+NET_IFACE_OFFS_READTIMER, r16
|
|
; check mode
|
|
ldd r16, Y+COM2W_IFACE_OFFS_MODE
|
|
cpi r16, COM2W_MODE_READING
|
|
brne com2wnReadNextBit_end
|
|
; handle received bit
|
|
ldd r16, Y+COM2W_IFACE_OFFS_CURRBYTE
|
|
ldd r18, Y+COM2W_IFACE_OFFS_BITCOUNTER
|
|
tst r17 ; data port input
|
|
clc
|
|
breq com2wnReadNextBit_clockData
|
|
sec
|
|
com2wnReadNextBit_clockData:
|
|
ror r16
|
|
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
|
|
inc r18 ; bit counter
|
|
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r18
|
|
cpi r18, 8
|
|
brne com2wnReadNextBit_end
|
|
; write byte into buffer
|
|
push xl
|
|
push xh
|
|
rcall com2wnByteRecvd ; (r16, r17, r18, X)
|
|
pop xh
|
|
pop xl
|
|
; prepare for next byte
|
|
clr r16
|
|
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r16
|
|
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
|
|
com2wnReadNextBit_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnByteRecvd
|
|
;
|
|
; @param r16 byte received
|
|
; @param Y pointer to interface data
|
|
; @return CFLAG set if okay, cleared on error
|
|
; @clobbers r16, r17, r18, X
|
|
|
|
com2wnByteRecvd:
|
|
ldd xl, Y+COM2W_IFACE_OFFS_BUFPOS_LOW
|
|
ldd xh, Y+COM2W_IFACE_OFFS_BUFPOS_HIGH
|
|
ldd r17, Y+COM2W_IFACE_OFFS_BUFLEFT
|
|
ldd r18, Y+COM2W_IFACE_OFFS_BUFUSED
|
|
tst r17
|
|
breq com2wnByteRecvd_overflow
|
|
st X+, r16
|
|
std Y+COM2W_IFACE_OFFS_BUFPOS_LOW, xl
|
|
std Y+COM2W_IFACE_OFFS_BUFPOS_HIGH, xh
|
|
inc r18
|
|
std Y+COM2W_IFACE_OFFS_BUFUSED, r18
|
|
dec r17
|
|
std Y+COM2W_IFACE_OFFS_BUFLEFT, r17
|
|
breq com2wnByteRecvd_msgComplete
|
|
cpi r18, 2
|
|
sec
|
|
brne com2wnByteRecvd_end
|
|
|
|
; determine msg size
|
|
inc r16 ; last byte was payload length, add byte for crc
|
|
cp r17, r16 ; compare remaining length against remaining space
|
|
brcs com2wnByteRecvd_eMsgSize
|
|
std Y+COM2W_IFACE_OFFS_BUFLEFT, r16
|
|
tst r16
|
|
sec
|
|
brne com2wnByteRecvd_end
|
|
com2wnByteRecvd_msgComplete:
|
|
push r19 ; pushing these registers is now only needed *here* for every
|
|
push r20 ; message received. Otherwise they would have been pushed
|
|
push r24 ; on every bit adding much more execution time to the
|
|
push r25 ; irq service routine
|
|
push zl
|
|
push zh
|
|
rcall com2wnMsgReceived ; (R16, R17, R18, R19, R20, R24, R25, X, Z)
|
|
pop zh
|
|
pop zl
|
|
pop r25
|
|
pop r24
|
|
pop r20
|
|
pop r19
|
|
rjmp com2wnByteRecvd_end
|
|
com2wnByteRecvd_overflow:
|
|
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
|
|
rjmp com2wnByteRecvd_error
|
|
com2wnByteRecvd_eMsgSize:
|
|
|
|
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
|
|
com2wnByteRecvd_error:
|
|
push r24
|
|
push r25
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
pop r25
|
|
pop r24
|
|
ldi r16, COM2W_MODE_SKIPPING ; error, enter skipping mode
|
|
rcall com2wSetMode
|
|
clc
|
|
com2wnByteRecvd_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnMsgReceived
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @return CFLAG set if okay, cleared on error
|
|
; @clobbers R16, R17, R18, X, Z (R19, R20, R24, R25)
|
|
|
|
com2wnMsgReceived:
|
|
mov xl, yl
|
|
mov xh, yh
|
|
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
|
|
mov zl, xl ; Z=buffer in IFACE
|
|
mov zh, xh
|
|
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
|
brcc com2wnMsgReceived_econtent
|
|
; msg valid, alloc buffer
|
|
rcall NET_Buffer_Alloc ; X=buffer, R16=bufnum (R16, R17, X)
|
|
brcc com2wnMsgReceived_enobuf
|
|
mov r18, r16 ; buffer num
|
|
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
|
|
adiw xh:xl, 1 ; skip buffer header
|
|
ldd r17, Y+COM2W_IFACE_OFFS_BUFUSED ; always is at least 2 here
|
|
com2wnMsgReceived_copyLoop:
|
|
ld r16, Z+
|
|
st X+, r16
|
|
dec r17
|
|
brne com2wnMsgReceived_copyLoop
|
|
mov r16, r18 ; buffer num
|
|
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
|
|
brcc com2wnMsgReceived_enoadd
|
|
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
sec
|
|
rjmp com2wnMsgReceived_setIdleAndEnd
|
|
com2wnMsgReceived_enoadd:
|
|
rcall NET_Buffer_ReleaseByNum
|
|
rjmp com2wnMsgReceived_enobuf
|
|
com2wnMsgReceived_enobuf:
|
|
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
|
rjmp com2wnMsgReceived_err
|
|
com2wnMsgReceived_econtent:
|
|
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
|
com2wnMsgReceived_err:
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
clc
|
|
com2wnMsgReceived_setIdleAndEnd:
|
|
ldi r16, COM2W_MODE_IDLE
|
|
rcall com2wSetMode ; (R17, doesn't change CFLAG!)
|
|
com2wnMsgReceived_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
#endif ; AVR_MODULES_COM2W_COM2WN_RECV_H
|
|
|