290 lines
6.8 KiB
NASM
290 lines
6.8 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_RUN_H
|
|
#define AVR_MODULES_COM2W_COM2WN_RUN_H
|
|
|
|
|
|
; WORK IN PROGRESS
|
|
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnLowLevelRun
|
|
;
|
|
|
|
com2wnLowLevelRunOnePort:
|
|
ldi yl, LOW(com2wnIoRingBuffer)
|
|
ldi yh, HIGH(com2wnIoRingBuffer)
|
|
rcall RingBufferY_ReadByteGuarded ; (R17, R18, X)
|
|
brcc com2wnLowLevelRunOnePort_ret
|
|
|
|
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)
|
|
com2wnLowLevelRunOnePort_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
|
|
push r16
|
|
push r18
|
|
push r19
|
|
mov r17, r16 ; same byte on onePort system
|
|
rcall com2wnActOnClock ; (r16, r17, r18, X)
|
|
pop r19
|
|
pop r18
|
|
pop r16
|
|
com2wnLowLevelRunOnePort_nextIface:
|
|
adiw yh:yl, COM2W_IFACE_SIZE
|
|
dec r19
|
|
brne com2wnLowLevelRunOnePort_loop
|
|
sec
|
|
com2wnLowLevelRunOnePort_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wPeriodically @global
|
|
;
|
|
; @clobbers R16, Y
|
|
|
|
com2wPeriodically:
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
rcall NET_Interface_Periodically
|
|
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
|
|
inc r16
|
|
breq com2wPeriodically_end
|
|
std Y+COM2W_IFACE_OFFS_MODECOUNTER, r16
|
|
com2wPeriodically_end:
|
|
out SREG, r15
|
|
pop r15
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wSetMode
|
|
;
|
|
; Doesn't change processor status flags!
|
|
;
|
|
; @param R16 mode
|
|
; @clobbers R17
|
|
|
|
com2wSetMode:
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
ldd r17, Y+COM2W_IFACE_OFFS_MODE
|
|
cp r16, r17
|
|
breq com2wSetMode_end
|
|
std Y+COM2W_IFACE_OFFS_MODE, r16
|
|
clr r17
|
|
std Y+COM2W_IFACE_OFFS_MODECOUNTER, r17
|
|
com2wSetMode_end:
|
|
out SREG, r15
|
|
pop r15
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnStartReading
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers R16, R17, X
|
|
|
|
com2wnStartReading:
|
|
mov xl, yl
|
|
mov xh, yh
|
|
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
|
|
std Y+COM2W_IFACE_OFFS_BUFPOS_LOW, xl
|
|
std Y+COM2W_IFACE_OFFS_BUFPOS_HIGH, xh
|
|
ldi r16, COM2W_BUFFER_SIZE
|
|
std Y+COM2W_IFACE_OFFS_BUFLEFT, r16
|
|
clr r16
|
|
std Y+COM2W_IFACE_OFFS_BUFUSED, r16
|
|
ldi r16, COM2W_MODE_READING
|
|
rcall com2wSetMode ; (R17)
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnRunMode
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers all
|
|
|
|
com2wnRunMode:
|
|
cpi r16, COM2W_MODE_NUM
|
|
brcs com2wnRunMode_jump
|
|
ldi r16, COM2W_MODE_IDLE ; unknown mode, set to idle
|
|
rcall com2wSetMode ; (R17)
|
|
sec
|
|
ret
|
|
com2wnRunMode_jump:
|
|
ldi zl, LOW(com2wnModeJumpTable)
|
|
ldi zh, HIGH(com2wnModeJumpTable)
|
|
add zl, r16
|
|
adc zh, r16
|
|
sub zh, r16
|
|
ijmp
|
|
com2wnModeJumpTable:
|
|
rjmp com2wnRunIdle
|
|
rjmp com2wnRunReading
|
|
rjmp com2wnRunSkipping
|
|
rjmp com2wnRunWriting
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnRunIdle
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers R16, R17, R22, R24, R25, X
|
|
|
|
com2wnRunIdle:
|
|
;rjmp com2wnRunIdle_end ; DEBUG
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
; look for outbound message
|
|
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
|
|
brcs com2wnRunIdle_haveMsg
|
|
out SREG, r15
|
|
pop r15
|
|
clc
|
|
rjmp com2wnRunIdle_end
|
|
|
|
com2wnRunIdle_haveMsg:
|
|
mov r24, r16
|
|
ldi r16, COM2W_MODE_WRITING
|
|
rcall com2wSetMode ; (R17)
|
|
mov r16, r24
|
|
out SREG, r15
|
|
pop r15
|
|
|
|
push r16
|
|
rcall NET_Buffer_Locate ; (R17)
|
|
adiw xh:xl, 1
|
|
rcall com2w0SendMsg ; (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
|
|
rcall com2wSetMode ; (R17)
|
|
out SREG, r15 ; restore SREG
|
|
pop r15
|
|
pop r16
|
|
brcc com2wnRunIdle_end
|
|
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
|
|
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
|
out SREG, r15
|
|
pop r15
|
|
sec
|
|
com2wnRunIdle_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnRunReading
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers none
|
|
|
|
com2wnRunReading:
|
|
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
|
|
ldd r16, Y+NET_IFACE_OFFS_READTIMER
|
|
cpi r16, COM2W_READING_MAXREADCOUNTER
|
|
brcc com2wnRunReading_goIdle
|
|
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
|
|
cpi r16, COM2W_READING_MAXMODECOUNTER
|
|
brcc com2wnRunReading_goIdle
|
|
clc
|
|
rjmp com2wnRunReading_end
|
|
com2wnRunReading_goIdle:
|
|
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
ldi r16, COM2W_MODE_IDLE
|
|
rcall com2wSetMode ; (r17)
|
|
sec
|
|
com2wnRunReading_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnRunSkipping
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers r16 (r17)
|
|
|
|
com2wnRunSkipping:
|
|
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
|
|
ldd r16, Y+NET_IFACE_OFFS_READTIMER
|
|
cpi r16, COM2W_SKIPPING_MAXREADCOUNTER
|
|
brcc com2wnRunSkipping_goIdle
|
|
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
|
|
cpi r16, COM2W_SKIPPING_MAXMODECOUNTER
|
|
brcc com2wnRunSkipping_goIdle
|
|
clc
|
|
rjmp com2wnRunSkipping_end
|
|
com2wnRunSkipping_goIdle:
|
|
ldi r16, COM2W_MODE_IDLE
|
|
rcall com2wSetMode ; (r17)
|
|
sec
|
|
com2wnRunSkipping_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine com2wnRunWriting
|
|
;
|
|
; @param Y pointer to interface data in SRAM
|
|
; @clobbers none
|
|
|
|
com2wnRunWriting:
|
|
; TODO: check for timeout
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
#endif ; AVR_MODULES_COM2W_COM2WN_RUN_H
|
|
|
|
|