241 lines
6.2 KiB
NASM
241 lines
6.2 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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
; ***************************************************************************
|
|
; defines
|
|
|
|
.equ NET_UART_MSG_INTERVAL = 1
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; data
|
|
|
|
.dseg
|
|
|
|
|
|
netUartIface: .byte UART_HW_IFACE_SIZE
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ComOnUart0_Init @global
|
|
;
|
|
|
|
NET_Uart_Init:
|
|
ldi yl, LOW(netUartIface)
|
|
ldi yh, HIGH(netUartIface)
|
|
rcall UART_HW_Interface_Init
|
|
rcall UART_Init
|
|
rcall ATTN_Init
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine NET_Uart_Run @global
|
|
;
|
|
; @clobbers all
|
|
|
|
NET_Uart_Run:
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
ldi yl, LOW(netUartIface)
|
|
ldi yh, HIGH(netUartIface)
|
|
rcall netUartRunReadModes
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMODE ; test for active read mode
|
|
cpi r16, UART_HW_READMODE_IDLE
|
|
brne NET_Uart_Run_end
|
|
rcall netUartRunWriteModes ; only call write routine if read idle
|
|
NET_Uart_Run_end:
|
|
pop r15
|
|
out SREG, r15
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine NET_Uart_Periodically
|
|
;
|
|
; @clobbers all, !Y
|
|
|
|
NET_Uart_Periodically:
|
|
ldi yl, LOW(netUartIface)
|
|
ldi yh, HIGH(netUartIface)
|
|
rjmp NET_Interface_Periodically
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine netUartRunWriteModes
|
|
;
|
|
; @clobbers all, !Y
|
|
|
|
netUartRunWriteModes:
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMODE ; handle write functions
|
|
cpi r16, UART_HW_WRITEMODE_IDLE
|
|
breq netUartRunWriteIdle
|
|
cpi r16, UART_HW_WRITEMODE_WRITING
|
|
breq netUartRunWriting
|
|
cpi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
|
|
breq netUartRunWaitBufferEmpty
|
|
cpi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY
|
|
breq netUartRunWriteBufferEmpty
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
netUartRunWaitBufferEmpty:
|
|
rcall UART_GetFlags ; (none)
|
|
ldi r17, (1<<UART_FLAGS_LASTBYTESENT_BIT) | (1<<UART_FLAGS_SWUNDERRUN_BIT)
|
|
eor r16, r17
|
|
andi r16, (1<<UART_FLAGS_LASTBYTESENT_BIT) | (1<<UART_FLAGS_SWUNDERRUN_BIT)
|
|
brne netUartRunWaitBufferEmpty_end
|
|
rcall UART_StopTx
|
|
ldi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY
|
|
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
|
|
rjmp netUartRunWriteBufferEmpty ; we just entered new write mode
|
|
netUartRunWaitBufferEmpty_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
netUartRunWriteBufferEmpty:
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM
|
|
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
|
ldi r16, 0xff
|
|
std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r16
|
|
rcall ATTN_SetHighEnableIrq ; release bus
|
|
ldi r16, UART_HW_WRITEMODE_IDLE
|
|
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
netUartRunWriteIdle:
|
|
ldd r16, Y+NET_IFACE_OFFS_WRITETIMER
|
|
cpi r16, NET_UART_MSG_INTERVAL ; wait a bit between messages
|
|
brcs netUartRunWriteIdle_end
|
|
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
|
|
brcc netUartRunWriteIdle_end ; no outmsg in queue
|
|
rcall ATTN_IsHigh
|
|
brcc netUartRunWriteIdle_end ; ATTN low, jmp
|
|
mov r17, r16
|
|
rcall ATTN_SetLowDisableIrq ; reserve bus as soon as possible (R16)
|
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
|
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
|
|
mov r16, r17
|
|
rcall NET_Buffer_Locate ; (R17)
|
|
rcall UART_HW_Interface_SetWriteBuffer
|
|
ldi r17, UART_HW_WRITEMODE_WRITING
|
|
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r17
|
|
rcall NET_Interface_GetNextOutgoingMsgNum ; take msg from queue (R17, R18, X)
|
|
rjmp netUartRunWriting ; just entered writing mode
|
|
netUartRunWriteIdle_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
netUartRunWriting:
|
|
ldd r19, Y+UART_HW_IFACE_OFFS_WRITEBUFLEFT
|
|
tst r19
|
|
breq netUartRunWriting_checkTxEn
|
|
rcall UART_GetFlags ; r16=flags (none)
|
|
andi r16, (1<<UART_FLAGS_SWUNDERRUN_BIT) | (1<<UART_FLAGS_LASTBYTESENT_BIT)
|
|
brne netUartRunWriting_error ; got an error while still bytes to send
|
|
push yl
|
|
push yh
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_LOW
|
|
ldd zh, Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_HIGH
|
|
clr r16
|
|
std Y+NET_IFACE_OFFS_WRITETIMER, r16
|
|
netUartRunWriting_loop:
|
|
ld r16, Z
|
|
rcall UART_WriteByte ; (R17, R18, X, Y)
|
|
brcc netUartRunWriting_loopEnd
|
|
adiw zh:zl, 1
|
|
dec r19
|
|
brne netUartRunWriting_loop
|
|
netUartRunWriting_loopEnd:
|
|
pop zl
|
|
pop zh
|
|
pop yh
|
|
pop yl
|
|
std Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_LOW, zl
|
|
std Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_HIGH, zh
|
|
std Y+UART_HW_IFACE_OFFS_WRITEBUFLEFT, r19
|
|
netUartRunWriting_checkTxEn:
|
|
rcall UART_GetFlags ; (none)
|
|
sbrs r16, UART_FLAGS_TXEN_BIT
|
|
rcall UART_StartTx ; (R16)
|
|
tst r19
|
|
brne netUartRunWriting_end
|
|
ldi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
|
|
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
|
|
rjmp netUartRunWaitBufferEmpty ; we just entered new write mode
|
|
netUartRunWriting_error:
|
|
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
|
|
rcall netUartAbortTx
|
|
netUartRunWriting_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine netUartAbortTx
|
|
;
|
|
; @clobbers all, !Y
|
|
|
|
netUartAbortTx:
|
|
rcall NET_Interface_IncCounter16
|
|
rcall UART_StopTx
|
|
rcall UART_ResetWriteBuffer
|
|
rcall ATTN_SetHighEnableIrq
|
|
ldi r16, UART_HW_WRITEMODE_IDLE
|
|
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
|
|
ldi r17, 0xff
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM
|
|
std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r17
|
|
rjmp NET_Buffer_ReleaseByNum
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
netUartRunReadModes:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|