try new implementation of UART code for m8515.
This commit is contained in:
240
avr/modules/uart_hw/net_uart.asm
Normal file
240
avr/modules/uart_hw/net_uart.asm
Normal file
@@ -0,0 +1,240 @@
|
||||
; ***************************************************************************
|
||||
; 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user