avr: added module uart_fd

This module uses hardware UART of MCUs in full duplex mode.
This commit is contained in:
Martin Preuss
2025-08-23 00:08:25 +02:00
parent 3a7951be16
commit 08d420a871
10 changed files with 1955 additions and 0 deletions

View File

@@ -133,6 +133,23 @@
#endif #endif
#ifdef MODULES_UARTFD0
.include "modules/uart_fd/defs.asm"
.include "modules/uart_fd/macros.asm"
.include "modules/uart_fd/uartfd0.asm"
#endif
#ifdef MODULES_UARTFD1
.include "modules/uart_fd/defs.asm"
.include "modules/uart_fd/macros.asm"
.include "modules/uart_fd/uartfd1.asm"
#endif
#ifdef MODULES_CLOCK #ifdef MODULES_CLOCK
.include "modules/clock/main.asm" .include "modules/clock/main.asm"
#endif #endif

View File

@@ -127,6 +127,14 @@ onSystemTimerTick:
bigcall TtyOnUart1_Periodically bigcall TtyOnUart1_Periodically
#endif #endif
#ifdef MODULES_UARTFD0
bigcall UARTFD0_Every100ms
#endif
#ifdef MODULES_UARTFD1
bigcall UARTFD1_Every100ms
#endif
#ifdef MODULES_COMONUART0 #ifdef MODULES_COMONUART0
bigcall ComOnUart0_Periodically bigcall ComOnUart0_Periodically
#endif #endif

View File

@@ -73,6 +73,14 @@ initModules:
bigcall TtyOnUart1_Init bigcall TtyOnUart1_Init
#endif #endif
#ifdef MODULES_UARTFD0
bigcall UARTFD0_Init
#endif
#ifdef MODULES_UARTFD1
bigcall UARTFD1_Init
#endif
#ifdef MODULES_COMONUART0 #ifdef MODULES_COMONUART0
bigcall ComOnUart0_Init bigcall ComOnUart0_Init
#endif #endif
@@ -202,6 +210,21 @@ runModules:
pop r16 pop r16
#endif #endif
#ifdef MODULES_UARTFD0
push r16
bigcall UARTFD0_Run
pop r16
sbci r16, 0
#endif
#ifdef MODULES_UARTFD1
push r16
bigcall UARTFD1_Run
pop r16
sbci r16, 0
#endif
#ifdef MODULES_COMONUART0 #ifdef MODULES_COMONUART0
push r16 push r16
bigcall ComOnUart0_Run bigcall ComOnUart0_Run

View File

@@ -0,0 +1,259 @@
; ***************************************************************************
; 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. *
; ***************************************************************************
; ***************************************************************************
; Source file for temperature sensor node on AtTiny 84
;
; This is for the full system (i.e. not the boot loader).
;
; All definitions and changes should go into this file.
;
;
; ***************************************************************************
;.equ clock=1000000 ; Define the clock frequency
.equ clock=8000000 ; Define the clock frequency
.nolist
.include "include/tn841def.inc" ; Define device ATtiny841
.list
.include "../defs.asm"
.include "version.asm"
;.include "defs_all.asm"
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_wait.asm"
.include "common/utils_io.asm"
; ***************************************************************************
; defines
; ---------------------------------------------------------------------------
; generic
.equ COMONUART0_IFACENUM = 1
.equ TTYONUART1_IFACENUM = 2
; ---------------------------------------------------------------------------
; firmware settings including list of modules used
#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes
#define APP_STATS_NETDEV2
#define APP_ROUTER_NO_ADDR_MGR
#define MODULES_CLOCK
;#define MODULES_COM
;#define MODULES_COM_WITH_ADDR_PROTO
;#define MODULES_LED
#define MODULES_LED_SIMPLE
;#define MODULES_TWI_MASTER
;#define MODULES_LCD
;#define LCD_MINIMAL_FONT
;#define MODULES_SI7021
;#define MODULES_STATS
;#define MODULES_CNY70
;#define MODULES_REED
;#define MODULES_OWI_MASTER
;#define MODULES_DS18B20
;#define MODULES_MOTION
#define MODULES_NETWORK
#define MODULES_COM2W
;#define MODULES_COMONUART0
;#define MODULES_TTYONUART1
#define MODULES_UARTFD1
#define APPS_STATS
;#define APPS_NETWORK
#define APPS_ROUTER
.equ NET_BUFFERS_NUM = 10
.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming)
.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound)
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8
; ---------------------------------------------------------------------------
; defines for values
.equ VALUE_ID_DS18B20_TEMP = 0x06
.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88
.equ VALUE_ID_ROUTER_SETRANGE = 0x89
.equ COM_DATA0_DDR = COM_DATA_DDR
.equ COM_DATA0_INPUT = COM_DATA_INPUT
.equ COM_DATA0_OUTPUT = COM_DATA_OUTPUT
.equ COM_DATA0_PUE = COM_DATA_PUE
.equ COM_DATA0_PIN = COM_DATA_PIN
.equ COM_CLK0_DDR = COM_CLK_DDR
.equ COM_CLK0_INPUT = COM_CLK_INPUT
.equ COM_CLK0_OUTPUT = COM_CLK_OUTPUT
.equ COM_CLK0_PUE = COM_CLK_PUE
.equ COM_CLK0_PIN = COM_CLK_PIN
.equ COM_IRQ_ADDR_CLK0 = COM_IRQ_ADDR_CLK
.equ COM_IRQ_BIT_CLK0 = COM_IRQ_BIT_CLK
.equ COM_IRQ_GIFR_CLK0 = COM_IRQ_GIFR_CLK
.equ COM_IRQ_GIMSK_CLK0 = COM_IRQ_GIMSK_CLK
; ***************************************************************************
; code segment
.cseg
.org 000000
; ---------------------------------------------------------------------------
; Reset and interrupt vectors
rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system
reti ; 2: INT0 External Interrupt Request 0
rjmp com2wPcintIsr ; 3: PCINT0 Pin Change Interrupt 0
reti ; 4: PCINT1 Pin Change Interrupt 1
reti ; 5: WDT Watchdog Time-out
reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event
reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A
reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B
reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow
rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A
reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B
reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow
reti ; 13: ANA_COMP0 Analog Comparator 0
reti ; 14: ADC_READY ADC Conversion Complete
reti ; 15: EE_RDY (ERDY) EEPROM Ready
reti ; 16: ANA_COMP1 Analog Comparator 1
reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event
reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A
reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B
reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow
reti ; 21: SPI SPI Serial Transfer Complete
reti ; 22: USART0_RXS USART0 Rx Start
; rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
reti ; 23: USART0_RXC USART0 Rx Complete
reti ; 24: USART0_DRE USART0 Data Register Empty
reti ; 25: USART0_TXC USART0 Tx Complete
reti ; 26: USART1_RXS USART1 Rx Start
rjmp UARTFD1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete
rjmp UARTFD1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty
rjmp UARTFD1_TxCharIsr ; 29: USART1_TXC USART1 Tx Complete
reti ; 30: TWI Two-Wire-Interface
reti ; 31: RESERVED reserved
devInfoBlock: ; 12 bytes
devInfoManufacturer: .db 'A', 'Q', 'U', 'A'
devInfoId: .db DEVICEINFO_ID, 0
devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision
firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR
.db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL
; ---------------------------------------------------------------------------
; @routine firmwareStart @global
firmwareStart:
rjmp main
; @end
; ---------------------------------------------------------------------------
; @routine onSystemStart
onSystemStart:
ldi r16, 0xf0
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16
ret
; @end
onEvery100ms:
onEverySecond:
onEveryMinute:
onEveryHour:
onEveryDay:
ret
; ---------------------------------------------------------------------------
; @routine onEveryLoop
;
; Called on every loop (i.e. after awakening from sleep).
onEveryLoop:
ret
; @end
; ---------------------------------------------------------------------------
; @routine onMessageReceived
;
; Called on every message received
onMessageReceived:
clc
ret
; @end
; ***************************************************************************
; includes
.include "devices/all/hw_tn841.asm"
.include "devices/all/includes.asm"
.include "common/debug.asm"
; ---------------------------------------------------------------------------
; defines for network interface
.equ netInterfaceData = uartFd1_iface
.equ netInterfaceData2 = com2w_iface
; debug
push r18
push r19
rcall LedSimple_SetFastTiming
pop r19
pop r18

View File

@@ -31,6 +31,7 @@
uart_bitbang uart_bitbang
uart_bitbang2 uart_bitbang2
uart_irq uart_irq
uart_fd
uart_hw uart_hw
bootloader bootloader
f_keepup f_keepup

View File

@@ -0,0 +1,13 @@
<?xml?>
<gwbuild>
<extradist>
defs.asm
macros.asm
uartfd0.asm
</extradist>
</gwbuild>

View File

@@ -0,0 +1,47 @@
; ***************************************************************************
; 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_UARTFD_DEFS_ASM
#define AVR_MODULES_UARTFD_DEFS_ASM
.equ UARTFD_SKIPPING_TIME = 2
.equ UARTFD_READ_TIMEOUT = 2
.equ UARTFD_WRITE_TIMEOUT = 2
.equ UARTFD_IFACE_STATUS_BIT_OVERRUN = 0
.equ UARTFD_IFACE_STATUS_BIT_HWERR = 1
.equ UARTFD_IFACE_STATUS_BIT_BADMSGSIZE = 2
.equ UARTFD_IFACE_STATUS_BIT_SKIPPING = 3
.equ UARTFD_IFACE_SIZE_BUFFER = NET_BUFFERS_SIZE-1
.equ UARTFD_IFACE_OFFS_BEGIN = NET_IFACE_SIZE
.equ UARTFD_IFACE_OFFS_STATUS = UARTFD_IFACE_OFFS_BEGIN
.equ UARTFD_IFACE_OFFS_WPOS_LOW = UARTFD_IFACE_OFFS_BEGIN+1
.equ UARTFD_IFACE_OFFS_WPOS_HIGH = UARTFD_IFACE_OFFS_BEGIN+2
.equ UARTFD_IFACE_OFFS_WBUFLEFT = UARTFD_IFACE_OFFS_BEGIN+3
.equ UARTFD_IFACE_OFFS_WBUFNUM = UARTFD_IFACE_OFFS_BEGIN+4
.equ UARTFD_IFACE_OFFS_RPOS_LOW = UARTFD_IFACE_OFFS_BEGIN+5
.equ UARTFD_IFACE_OFFS_RPOS_HIGH = UARTFD_IFACE_OFFS_BEGIN+6
.equ UARTFD_IFACE_OFFS_RBUFUSED = UARTFD_IFACE_OFFS_BEGIN+7
.equ UARTFD_IFACE_OFFS_RBUFLEFT = UARTFD_IFACE_OFFS_BEGIN+8
.equ UARTFD_IFACE_OFFS_RBUFFER = UARTFD_IFACE_OFFS_BEGIN+9
.equ UARTFD_IFACE_SIZE = UARTFD_IFACE_OFFS_RBUFFER+UARTFD_IFACE_SIZE_BUFFER
#endif

View File

@@ -0,0 +1,204 @@
; ***************************************************************************
; 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_UARTFD_MACROS_ASM
#define AVR_MODULES_UARTFD_MACROS_ASM
.macro M_UARTFD_SET_CHARFORMAT
ldi r16, (1<<UCSZ@01) | (1<<UCSZ@00) ; 1 stop bit, 8 databits
outr UCSR@0C, r16
.endmacro
.macro M_UARTFD_SET_BAUDRATE
.if clock == 8000000
ldi r16, 25 ; (19.2Kb/s at 8MHz)
ldi r17, 0
.elif clock == 1000000
ldi r16, 2 ; (19.2Kb/s at 1MHz)
ldi r17, 0
.else
.error "Unhandled clock frequency"
.endif
outr UBRR@0H, r17
outr UBRR@0L, r16
.endmacro
.macro M_UARTFD_START_RX
inr r16, UCSR@0B
sbr r16, (1<<RXCIE@0) | (1<<RXEN@0) ; enable RX complete interrupt, enable receive
outr UCSR@0B, r16
.endmacro
.macro M_UARTFD_STOP_RX
inr r16, UCSR@0B
cbr r16, (1<<RXCIE@0) | (1<<RXEN@0) ; disable RX complete interrupt, disable receive
outr UCSR@0B, r16
.endmacro
.macro M_UARTFD_START_TX
inr r16, UCSR@0A
cbr r16, (1<<TXC@0) ; clear TXCn interrupt
outr UCSR@0A, r16
inr r16, UCSR@0B
sbr r16, (1<<UDRIE@0) | (1<<TXCIE@0) | (1<<TXEN@0) ; enable TX UDRE and TXC interrupt, enable transceive
outr UCSR@0B, r16
.endmacro
.macro M_UARTFD_STOP_TX
inr r16, UCSR@0B
cbr r16, (1<<UDRIE@0) | (1<<TXCIE@0) | (1<<TXEN@0) ; disable TX UDRE and TXC1 interrupt, enable transceive
outr UCSR@0B, r16
.endmacro
; ---------------------------------------------------------------------------
; @macro M_UARTFD_RXCHAR_ISR
;
; @clobbers r16, r17, X
.macro M_UARTFD_RXCHAR_ISR
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
brne l_resetReadTimer_% ; skipping
inr r16, UCSR@0A ; check for errors
andi r16, (1<<FE@0) | (1<<DOR@0) | (1<<UPE@0)
brne l_hwerr_%
inr r16, UCSR@0A
sbrs r16, RXC@0
rjmp l_end_% ; no data
inr r16, UDR@0 ; r16=received char
ldd r17, Y+UARTFD_IFACE_OFFS_RBUFLEFT
tst r17
breq l_overrun_%
dec r17
std Y+UARTFD_IFACE_OFFS_RBUFLEFT, r17
ldd r17, Y+UARTFD_IFACE_OFFS_RBUFUSED
inc r17
std Y+UARTFD_IFACE_OFFS_RBUFUSED, r17
ldd xl, Y+UARTFD_IFACE_OFFS_RPOS_LOW
ldd xh, Y+UARTFD_IFACE_OFFS_RPOS_HIGH
st X+, r16
std Y+UARTFD_IFACE_OFFS_RPOS_LOW, xl
std Y+UARTFD_IFACE_OFFS_RPOS_HIGH, xh
cpi r17, 2 ; exactly 2 bytes in buffer?
brne l_resetReadTimer_%
; determine message size
inc r16 ; last byte was payload length, add byte for crc
ldd r17, Y+UARTFD_IFACE_OFFS_RBUFLEFT
cp r17, r16 ; compare remaining length against remaining space
brcs l_badMsgSize_%
std Y+UARTFD_IFACE_OFFS_RBUFLEFT, r16
l_resetReadTimer_%:
clr r16
std Y+NET_IFACE_OFFS_READTIMER, r16 ; reset read timer
rjmp l_end_%
l_hwerr_%:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
ori r16, (1<<UARTFD_IFACE_STATUS_BIT_HWERR) | (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
rjmp l_end_%
l_badMsgSize_%:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
ori r16, (1<<UARTFD_IFACE_STATUS_BIT_BADMSGSIZE) | (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
rjmp l_end_%
l_overrun_%:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
ori r16, (1<<UARTFD_IFACE_STATUS_BIT_OVERRUN) | (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
l_end_%:
.endmacro
; @end
; ---------------------------------------------------------------------------
; @macro M_UARTFD_TXUDRE_ISR
;
; @clobbers R16, R17, X
.macro M_UARTFD_TXUDRE_ISR
lds r16, UCSR@0A ; check for UDRE flag
sbrs r16,UDRE@0
rjmp l_disable_irq_% ; not ready
; check whether we have an active write buffer
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq l_disable_irq_% ; no buffer
; check whether there is data in the buffer to send
ldd r17, Y+UARTFD_IFACE_OFFS_WBUFLEFT ; r17=bytes left
tst r17
breq l_disable_irq_% ; nothing left to write
; get read ptr, read byte, inc read ptr, store ptr and bytesLeft
ldd xl, Y+UARTFD_IFACE_OFFS_WPOS_LOW
ldd xh, Y+UARTFD_IFACE_OFFS_WPOS_HIGH
ld r16, X+ ; r16=byte to write
std Y+UARTFD_IFACE_OFFS_WPOS_LOW, xl
std Y+UARTFD_IFACE_OFFS_WPOS_HIGH, xh
dec r17
std Y+UARTFD_IFACE_OFFS_WBUFLEFT, r17
; send byte, reset write timer
sts UDR@0, r16
clr r16
std Y+NET_IFACE_OFFS_WRITETIMER, r16 ; reset write timer
; still bytes left to write?
tst r17
brne l_end_%
l_disable_irq_%:
; disable further UDRE interrupts
lds r16, UCSR@0B
cbr r16, (1<<UDRIE@0) ; disable TX data register empty interrupt
sts UCSR@0B, r16
l_end_%:
.endmacro
; @end
; ---------------------------------------------------------------------------
; @macro M_UARTFD_TXCHAR_ISR
;
; @clobbers R16, R17, X
.macro M_UARTFD_TXCHAR_ISR
; disable further TXC1 interrupts
inr r16, UCSR@0B
cbr r16, (1<<TXC@0) ; disable TXC interrupt
outr UCSR@0B, r16
.endmacro
; @end
#endif

View File

@@ -0,0 +1,687 @@
; ***************************************************************************
; 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_UARTFD_UARTFD0_ASM
#define AVR_MODULES_UARTFD_UARTFD0_ASM
.dseg
uartFd0_iface: .bytes UARTFD_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine UARTFD_Init @global
;
; @clobbers
UARTFD0_Init:
ldi yl, LOW(uartFd0_iface)
ldi yh, HIGH(uartFd0_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, 0xff
std Y+UARTFD_IFACE_OFFS_WBUFNUM, r16
clr r16
std Y+UARTFD_IFACE_OFFS_WBUFLEFT, r16
std Y+UARTFD_IFACE_OFFS_RBUFUSED, r16
std Y+UARTFD_IFACE_OFFS_RBUFLEFT, r16
M_UARTFD_SET_BAUDRATE 0
M_UARTFD_SET_CHARFORMAT 0
; always receive!
rcall uartFd0StartRx
ret
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD0_Every100ms @global
;
; @clobbers
UARTFD0_Every100ms:
ldi yl, LOW(uartFd0_iface)
ldi yh, HIGH(uartFd0_iface)
rcall NET_Interface_Periodically
ret
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD0_Run @global
;
; @return CFLAG set if something done
; @clobbers r22, (r16, r17, r18, r19, r20, r24, r25, X, Y, Z)
UARTFD0_Run:
ldi yl, LOW(uartFd0_iface)
ldi yh, HIGH(uartFd0_iface)
clr r22
rcall uartFd0RunRead ; (r16, r17, r18, r19, r20, r24, r25, X, Z)
sbci r22, 0
rcall uartFd0RunWrite ; (r16, r17, r18, r19, r24, r25, X)
sbci r22, 0
tst r22
clc
breq UARTFD0_Run_ret
sec
UARTFD0_Run_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0RunWrite
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r19 (r16, r18, r24, r25, X)
uartFd0RunWrite:
clr r19
rcall uartFd0CheckWriting ; (r16, X)
rcall uartFd0CheckMsgSent ; (r16, r24, r25)
sbci r19, 0
rcall uartFd0CheckSendMsg ; (r16, r17, r18, X)
sbci r19, 0
tst r19
clc
breq uartFd0RunWrite_ret
sec
uartFd0RunWrite_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (X)
uartFd0CheckWriting:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd0CheckWriting_ret
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFLEFT
tst r16
breq uartFd0CheckWriting_ret
ldd r16, Y+NET_IFACE_OFFS_WRITETIMER
cpi r16, UARTFD_WRITE_TIMEOUT
brcs uartFd0CheckWriting_ret
rcall uartFd0RestartWriting ; (r16, X)
uartFd0CheckWriting_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckSendMsg
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r17, r18, X)
uartFd0CheckSendMsg:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
brne uartFd0CheckSendMsg_clcRet
rcall NET_Interface_GetNextOutgoingMsgNum ; (R17, R18, X)
brcc uartFd0CheckSendMsg_ret
rcall uartFd0StartWriting ; (R16, R17, X)
sec
rjmp uartFd0CheckSendMsg_ret
uartFd0CheckSendMsg_clcRet:
clc
uartFd0CheckSendMsg_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckMsgSent
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r24, r25)
uartFd0CheckMsgSent:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd0CheckMsgSent_clcRet
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFLEFT
tst r16
brne uartFd0CheckMsgSent_clcRet
rcall uartFd0FinishWriting ; (r16, r24, r25)
sec
rjmp uartFd0CheckMsgSent_ret
uartFd0CheckMsgSent_clcRet:
clc
uartFd0CheckMsgSent_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0RunRead
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r17, r18, r19, r20, r24, r25, X, Z)
uartFd0RunRead:
; make sure received messages are stored ASAP
rcall uartFd0CheckMsgReceived ; (r16, r17, r18, r19, r20, r24, r25, X, Z)
push r15
in r15, SREG ; save CFLAG
; handle errors
rcall uartFd0CheckOverrun ; (r16, r24, r25)
rcall uartFd0CheckHwErr ; (r16, r24, r25)
rcall uartFd0CheckBadMsgSize ; (r16, r24, r25)
rcall uartFd0CheckSkipping ; (R16, X)
; clear error flags
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
cbr r16, (1<<UARTFD_IFACE_STATUS_BIT_OVERRUN) | (1<<UARTFD_IFACE_STATUS_BIT_HWERR) | (1<<UARTFD_IFACE_STATUS_BIT_BADMSGSIZE)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
; check timeout for reading
rcall uartFd0CheckReading
out SREG, r15 ; restore CFLAG from uartFd0CheckMsgReceived
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckSkipping
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (X)
uartFd0CheckSkipping:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
breq uartFd0CheckSkipping_ret
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, UARTFD_SKIPPING_TIME
brcs uartFd0CheckSkipping_ret
; leave skipping mode
push r15
in r15, SREG
cli
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
cbr r16, (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
rcall uartFd0RestartReading ; (R16, X)
out SREG, r15
pop r15
uartFd0CheckSkipping_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckReading
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (X)
uartFd0CheckReading:
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFLEFT
tst r16
breq uartFd0CheckReading_ret
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFUSED
tst r16
brne uartFd0CheckReading_ret
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, UARTFD_READ_TIMEOUT
brcs uartFd0CheckReading_ret
rcall uartFd0RestartReading ; (r16, X)
uartFd0CheckReading_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckMsgReceived
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r17, r18, r19, r20, r24, r25, X, Z)
uartFd0CheckMsgReceived:
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFLEFT
tst r16
brne uartFd0CheckMsgReceived_clcRet
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFUSED
tst r16
breq uartFd0CheckMsgReceived_clcRet
rcall uartFd0FinishReading ; (r16, r17, r18, r19, r20, r24, r25, X, Z)
rcall uartFd0StartReading ; (R16, X)
sec
rjmp uartFd0CheckMsgReceived_ret
uartFd0CheckMsgReceived_clcRet:
clc
uartFd0CheckMsgReceived_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckOverrun
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r24, r25
uartFd0CheckOverrun:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_OVERRUN)
breq uartFd0CheckOverrun_end
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd0CheckOverrun_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckHwErr
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r24, r25
uartFd0CheckHwErr:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_HWERR)
breq uartFd0CheckHwErr_end
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd0CheckHwErr_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0CheckBadMsgSize
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r24, r25
uartFd0CheckBadMsgSize:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_BADMSGSIZE)
breq uartFd0CheckBadMsgSize_end
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd0CheckBadMsgSize_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0StartReading
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, X
uartFd0StartReading:
rjmp uartFd0RestartReading ; (R16, X)
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0RestartReading
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, X
uartFd0RestartReading:
mov xl, yl
mov xh, yh
adiw xh:xl, UARTFD_IFACE_OFFS_RBUFFER
std Y+UARTFD_IFACE_OFFS_RPOS_LOW, xl
std Y+UARTFD_IFACE_OFFS_RPOS_HIGH, xh
clr r16
std Y+UARTFD_IFACE_OFFS_RBUFUSED, r16
std Y+NET_IFACE_OFFS_READTIMER, r16
ldi r16, UARTFD_IFACE_SIZE_BUFFER
std Y+UARTFD_IFACE_OFFS_RBUFLEFT, r16
; clear error flags
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
cbr r16, (1<<UARTFD_IFACE_STATUS_BIT_OVERRUN) | (1<<UARTFD_IFACE_STATUS_BIT_HWERR) | (1<<UARTFD_IFACE_STATUS_BIT_BADMSGSIZE)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0FinishReading
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r17, r18, X, Z (r19, r20, r24, r25)
uartFd0FinishReading:
mov xl, yl
mov xh, yh
adiw xh:xl, UARTFD_IFACE_OFFS_RBUFFER
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc uartFd0FinishReading_errorCrc
rcall NET_Buffer_Alloc ; R16=number, X=ptr (R16, R17, X)
brcc uartFd0FinishReading_errorMem
ldd r18, Y+NET_IFACE_OFFS_IFACENUM
ld r17, X
andi r17, 0xf0
or r17, r18
st X+, r17 ; store interface number
; copy to newly allocated buffer
mov zl, yl
mov zh, yh
adiw zh:zl, UARTFD_IFACE_OFFS_RBUFFER
ldd r17, Y+UARTFD_IFACE_OFFS_RBUFUSED
uartFd0FinishReading_copyLoop:
ld r18, Z+
st X+, r18
dec r17
brne uartFd0FinishReading_copyLoop
rcall NET_AddIncomingMsgNum
brcs uartFd0FinishReading_msgSaved
rcall NET_Buffer_ReleaseByNum ; (R16, X)
rjmp uartFd0FinishReading_errorMem
uartFd0FinishReading_msgSaved:
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rjmp uartFd0FinishReading_incCounter
uartFd0FinishReading_errorCrc:
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
rjmp uartFd0FinishReading_incCounter
uartFd0FinishReading_errorMem:
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
uartFd0FinishReading_incCounter:
rjmp NET_Interface_IncCounter16 ; (R24, R25)
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0StartWriting
;
; @param R16 number of buffer to write
; @param Y pointer to interface data in SRAM
; @clobbers R16, X (R17)
uartFd0StartWriting:
std Y+UARTFD_IFACE_OFFS_WBUFNUM, r16
rjmp uartFd0RestartWriting
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0RestartWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, X (R17)
uartFd0RestartWriting:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd0RestartWriting_ret
rcall NET_Buffer_Locate ; (R17)
brcc uartFd0RestartWriting_ret
adiw xh:xl, 1
adiw xh:xl, NETMSG_OFFS_MSGLEN
ld r16, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN
subi r16, -3 ; add destaddr, length, crc
std Y+UARTFD_IFACE_OFFS_WBUFLEFT, r16
std Y+UARTFD_IFACE_OFFS_WPOS_LOW, xl
std Y+UARTFD_IFACE_OFFS_WPOS_HIGH, xh
rcall uartFd0StartTx ; (r16)
uartFd0RestartWriting_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0FinishWriting
;
; @param R16 number of buffer to write
; @param Y pointer to interface data in SRAM
; @clobbers r16 (r24, r25)
uartFd0FinishWriting:
rcall uartFd0StopTx ; (r16)
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd0FinishWriting_ret
rcall NET_Buffer_ReleaseByNum ; (r16, X)
ldi r16, 0xff
std Y+UARTFD_IFACE_OFFS_WBUFNUM, r16
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd0FinishWriting_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0StartRx
;
; @clobbers R16
uartFd0StartRx:
M_UARTFD_START_RX 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0StopRx
;
; @clobbers R16
uartFd0StopRx:
M_UARTFD_STOP_RX 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0StartTx
;
; @clobbers R16
uartFd0StartTx:
M_UARTFD_START_TX 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0StopTx
;
; @clobbers R16
uartFd0StopTx:
M_UARTFD_STOP_TX 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0RxChar
;
; @clobbers r16, r17, X
uartFd0RxChar:
M_UARTFD_RXCHAR_ISR 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0TxUdre
;
; @clobbers r16, r17, X
uartFd0TxUdre:
M_UARTFD_TXUDRE_ISR 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd0TxChar
;
; @clobbers
uartFd0TxChar:
M_UARTFD_TXCHAR_ISR 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD0_RxCharIsr @global @isr
;
; @clobbers none
UARTFD0_RxCharIsr:
push r15
in r15, SREG
push yl
push yh
ldi yl, LOW(uartFd0_iface)
ldi yh, HIGH(uartFd0_iface)
push r16
push r17
push xl
push xh
rcall uartFd0RxChar
pop xh
pop xl
pop r17
pop r16
pop yh
pop yl
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD0_TxUdreIsr @global @isr
;
; @clobbers none
UARTFD0_TxUdreIsr:
push r15
in r15, SREG
push yl
push yh
ldi yl, LOW(uartFd0_iface)
ldi yh, HIGH(uartFd0_iface)
push r16
push r17
push xl
push xh
rcall uartFd0TxUdre
pop xh
pop xl
pop r17
pop r16
pop yh
pop yl
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD0_TxCharIsr @global @isr
;
; @clobbers none
UARTFD0_TxCharIsr:
push r15
in r15, SREG
push yl
push yh
ldi yl, LOW(uartFd0_iface)
ldi yh, HIGH(uartFd0_iface)
push r16
push r17
push xl
push xh
rcall uartFd0TxChar
pop xh
pop xl
pop r17
pop r16
pop yh
pop yl
out SREG, r15
pop r15
reti
; @end
#endif

View File

@@ -0,0 +1,696 @@
; ***************************************************************************
; 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_UARTFD_UARTFD1_ASM
#define AVR_MODULES_UARTFD_UARTFD1_ASM
; this is the tested version!
.dseg
uartFd1_iface: .byte UARTFD_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine UARTFD_Init @global
;
; @clobbers
UARTFD1_Init:
ldi yl, LOW(uartFd1_iface)
ldi yh, HIGH(uartFd1_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, 0xff
std Y+UARTFD_IFACE_OFFS_WBUFNUM, r16
clr r16
std Y+UARTFD_IFACE_OFFS_WBUFLEFT, r16
std Y+UARTFD_IFACE_OFFS_RBUFUSED, r16
std Y+UARTFD_IFACE_OFFS_RBUFLEFT, r16
M_UARTFD_SET_BAUDRATE 0
M_UARTFD_SET_CHARFORMAT 0
; always receive!
rcall uartFd1StartRx
ret
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD1_Every100ms @global
;
; @clobbers
UARTFD1_Every100ms:
ldi yl, LOW(uartFd1_iface)
ldi yh, HIGH(uartFd1_iface)
rcall NET_Interface_Periodically
ret
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD1_Run @global
;
; @return CFLAG set if something done
; @clobbers r22, (r16, r17, r18, r19, r20, r24, r25, X, Y, Z)
UARTFD1_Run:
ldi yl, LOW(uartFd1_iface)
ldi yh, HIGH(uartFd1_iface)
clr r22
push r15
in r15, SREG
cli ; disable irqs
rcall uartFd1RunRead ; (r16, r17, r18, r19, r20, r24, r25, X, Z)
sbci r22, 0
out SREG, r15 ; probably enable irqs
cli ; disable irqs
rcall uartFd1RunWrite ; (r16, r17, r18, r19, r24, r25, X)
sbci r22, 0
out SREG, r15 ; probably enable irqs
pop r15
tst r22
clc
breq UARTFD1_Run_ret
sec
UARTFD1_Run_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1RunWrite
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r19 (r16, r18, r24, r25, X)
uartFd1RunWrite:
clr r19
rcall uartFd1CheckWriting ; (r16, X)
rcall uartFd1CheckMsgSent ; (r16, r24, r25)
sbci r19, 0
rcall uartFd1CheckSendMsg ; (r16, r17, r18, X)
sbci r19, 0
tst r19
clc
breq uartFd1RunWrite_ret
sec
uartFd1RunWrite_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (X)
uartFd1CheckWriting:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd1CheckWriting_ret
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFLEFT
tst r16
breq uartFd1CheckWriting_ret
ldd r16, Y+NET_IFACE_OFFS_WRITETIMER
cpi r16, UARTFD_WRITE_TIMEOUT
brcs uartFd1CheckWriting_ret
rcall uartFd1RestartWriting ; (r16, X)
uartFd1CheckWriting_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckSendMsg
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r17, r18, X)
uartFd1CheckSendMsg:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
brne uartFd1CheckSendMsg_clcRet
rcall NET_Interface_GetNextOutgoingMsgNum ; (R17, R18, X)
brcc uartFd1CheckSendMsg_ret
rcall uartFd1StartWriting ; (R16, R17, X)
sec
rjmp uartFd1CheckSendMsg_ret
uartFd1CheckSendMsg_clcRet:
clc
uartFd1CheckSendMsg_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckMsgSent
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r24, r25)
uartFd1CheckMsgSent:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd1CheckMsgSent_clcRet
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFLEFT
tst r16
brne uartFd1CheckMsgSent_clcRet
rcall uartFd1FinishWriting ; (r16, r24, r25)
sec
rjmp uartFd1CheckMsgSent_ret
uartFd1CheckMsgSent_clcRet:
clc
uartFd1CheckMsgSent_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1RunRead
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r17, r18, r19, r20, r24, r25, X, Z)
uartFd1RunRead:
; make sure received messages are stored ASAP
rcall uartFd1CheckMsgReceived ; (r16, r17, r18, r19, r20, r24, r25, X, Z)
push r15
in r15, SREG ; save CFLAG
; handle errors
rcall uartFd1CheckOverrun ; (r16, r24, r25)
rcall uartFd1CheckHwErr ; (r16, r24, r25)
rcall uartFd1CheckBadMsgSize ; (r16, r24, r25)
rcall uartFd1CheckSkipping ; (r16, X)
; clear error flags
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
cbr r16, (1<<UARTFD_IFACE_STATUS_BIT_OVERRUN) | (1<<UARTFD_IFACE_STATUS_BIT_HWERR) | (1<<UARTFD_IFACE_STATUS_BIT_BADMSGSIZE)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
; check timeout for reading
rcall uartFd1CheckReading
out SREG, r15 ; restore CFLAG from uartFd1CheckMsgReceived
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckSkipping
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (X)
uartFd1CheckSkipping:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
breq uartFd1CheckSkipping_ret
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, UARTFD_SKIPPING_TIME
brcs uartFd1CheckSkipping_ret
; leave skipping mode
push r15
in r15, SREG
cli
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
cbr r16, (1<<UARTFD_IFACE_STATUS_BIT_SKIPPING)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
rcall uartFd1RestartReading ; (R16, X)
out SREG, r15
pop r15
uartFd1CheckSkipping_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckReading
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (X)
uartFd1CheckReading:
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFLEFT
tst r16
breq uartFd1CheckReading_ret
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFUSED
tst r16
brne uartFd1CheckReading_ret
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, UARTFD_READ_TIMEOUT
brcs uartFd1CheckReading_ret
rcall uartFd1RestartReading ; (r16, X)
uartFd1CheckReading_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckMsgReceived
;
; @param Y pointer to interface data in SRAM
; @return CFLAG set if something done
; @clobbers r16 (r17, r18, r19, r20, r24, r25, X, Z)
uartFd1CheckMsgReceived:
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFLEFT
tst r16
brne uartFd1CheckMsgReceived_clcRet
ldd r16, Y+UARTFD_IFACE_OFFS_RBUFUSED
tst r16
breq uartFd1CheckMsgReceived_clcRet
rcall uartFd1FinishReading ; (r16, r17, r18, r19, r20, r24, r25, X, Z)
rcall uartFd1StartReading ; (R16, X)
sec
rjmp uartFd1CheckMsgReceived_ret
uartFd1CheckMsgReceived_clcRet:
clc
uartFd1CheckMsgReceived_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckOverrun
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r24, r25
uartFd1CheckOverrun:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_OVERRUN)
breq uartFd1CheckOverrun_end
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd1CheckOverrun_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckHwErr
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r24, r25
uartFd1CheckHwErr:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_HWERR)
breq uartFd1CheckHwErr_end
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd1CheckHwErr_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1CheckBadMsgSize
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r24, r25
uartFd1CheckBadMsgSize:
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
andi r16, (1<<UARTFD_IFACE_STATUS_BIT_BADMSGSIZE)
breq uartFd1CheckBadMsgSize_end
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd1CheckBadMsgSize_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1StartReading
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, X
uartFd1StartReading:
rjmp uartFd1RestartReading ; (R16, X)
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1RestartReading
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, X
uartFd1RestartReading:
mov xl, yl
mov xh, yh
adiw xh:xl, UARTFD_IFACE_OFFS_RBUFFER
std Y+UARTFD_IFACE_OFFS_RPOS_LOW, xl
std Y+UARTFD_IFACE_OFFS_RPOS_HIGH, xh
clr r16
std Y+UARTFD_IFACE_OFFS_RBUFUSED, r16
std Y+NET_IFACE_OFFS_READTIMER, r16
ldi r16, UARTFD_IFACE_SIZE_BUFFER
std Y+UARTFD_IFACE_OFFS_RBUFLEFT, r16
; clear error flags
ldd r16, Y+UARTFD_IFACE_OFFS_STATUS
cbr r16, (1<<UARTFD_IFACE_STATUS_BIT_OVERRUN) | (1<<UARTFD_IFACE_STATUS_BIT_HWERR) | (1<<UARTFD_IFACE_STATUS_BIT_BADMSGSIZE)
std Y+UARTFD_IFACE_OFFS_STATUS, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1FinishReading
;
; @param Y pointer to interface data in SRAM
; @clobbers r16, r17, r18, X, Z (r19, r20, r24, r25)
uartFd1FinishReading:
mov xl, yl
mov xh, yh
adiw xh:xl, UARTFD_IFACE_OFFS_RBUFFER
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc uartFd1FinishReading_errorCrc
rcall NET_Buffer_Alloc ; R16=number, X=ptr (R16, R17, X)
brcc uartFd1FinishReading_errorMem
ldd r18, Y+NET_IFACE_OFFS_IFACENUM
ld r17, X
andi r17, 0xf0
or r17, r18
st X+, r17 ; store interface number
; copy to newly allocated buffer
mov zl, yl
mov zh, yh
adiw zh:zl, UARTFD_IFACE_OFFS_RBUFFER
ldd r17, Y+UARTFD_IFACE_OFFS_RBUFUSED
uartFd1FinishReading_copyLoop:
ld r18, Z+
st X+, r18
dec r17
brne uartFd1FinishReading_copyLoop
rcall NET_AddIncomingMsgNum
brcs uartFd1FinishReading_msgSaved
rcall NET_Buffer_ReleaseByNum ; (R16, X)
rjmp uartFd1FinishReading_errorMem
uartFd1FinishReading_msgSaved:
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rjmp uartFd1FinishReading_incCounter
uartFd1FinishReading_errorCrc:
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
rjmp uartFd1FinishReading_incCounter
uartFd1FinishReading_errorMem:
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
uartFd1FinishReading_incCounter:
rjmp NET_Interface_IncCounter16 ; (R24, R25)
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1StartWriting
;
; @param R16 number of buffer to write
; @param Y pointer to interface data in SRAM
; @clobbers R16, X (R17)
uartFd1StartWriting:
std Y+UARTFD_IFACE_OFFS_WBUFNUM, r16
rjmp uartFd1RestartWriting
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1RestartWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, X (R17)
uartFd1RestartWriting:
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd1RestartWriting_ret
rcall NET_Buffer_Locate ; (R17)
brcc uartFd1RestartWriting_ret
adiw xh:xl, 1
adiw xh:xl, NETMSG_OFFS_MSGLEN
ld r16, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN
subi r16, -3 ; add destaddr, length, crc
std Y+UARTFD_IFACE_OFFS_WBUFLEFT, r16
std Y+UARTFD_IFACE_OFFS_WPOS_LOW, xl
std Y+UARTFD_IFACE_OFFS_WPOS_HIGH, xh
rcall uartFd1StartTx ; (r16)
uartFd1RestartWriting_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1FinishWriting
;
; @param R16 number of buffer to write
; @param Y pointer to interface data in SRAM
; @clobbers r16 (r24, r25)
uartFd1FinishWriting:
rcall uartFd1StopTx ; (r16)
ldd r16, Y+UARTFD_IFACE_OFFS_WBUFNUM
cpi r16, 0xff
breq uartFd1FinishWriting_ret
rcall NET_Buffer_ReleaseByNum ; (r16, X)
ldi r16, 0xff
std Y+UARTFD_IFACE_OFFS_WBUFNUM, r16
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
uartFd1FinishWriting_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1StartRx
;
; @clobbers R16
uartFd1StartRx:
M_UARTFD_START_RX 1
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1StopRx
;
; @clobbers R16
uartFd1StopRx:
M_UARTFD_STOP_RX 1
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1StartTx
;
; @clobbers R16
uartFd1StartTx:
M_UARTFD_START_TX 1
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1StopTx
;
; @clobbers R16
uartFd1StopTx:
M_UARTFD_STOP_TX 1
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1RxChar
;
; @clobbers r16, r17, X
uartFd1RxChar:
M_UARTFD_RXCHAR_ISR 1
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1TxUdre
;
; @clobbers r16, r17, X
uartFd1TxUdre:
M_UARTFD_TXUDRE_ISR 1
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartFd1TxChar
;
; @clobbers
uartFd1TxChar:
M_UARTFD_TXCHAR_ISR 1
ret
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD1_RxCharIsr @global @isr
;
; @clobbers none
UARTFD1_RxCharIsr:
push r15
in r15, SREG
push yl
push yh
ldi yl, LOW(uartFd1_iface)
ldi yh, HIGH(uartFd1_iface)
push r16
push r17
push xl
push xh
rcall uartFd1RxChar
pop xh
pop xl
pop r17
pop r16
pop yh
pop yl
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD1_TxUdreIsr @global @isr
;
; @clobbers none
UARTFD1_TxUdreIsr:
push r15
in r15, SREG
push yl
push yh
ldi yl, LOW(uartFd1_iface)
ldi yh, HIGH(uartFd1_iface)
push r16
push r17
push xl
push xh
rcall uartFd1TxUdre
pop xh
pop xl
pop r17
pop r16
pop yh
pop yl
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine UARTFD1_TxCharIsr @global @isr
;
; @clobbers none
UARTFD1_TxCharIsr:
push r15
in r15, SREG
push yl
push yh
ldi yl, LOW(uartFd1_iface)
ldi yh, HIGH(uartFd1_iface)
push r16
push r17
push xl
push xh
rcall uartFd1TxChar
pop xh
pop xl
pop r17
pop r16
pop yh
pop yl
out SREG, r15
pop r15
reti
; @end
#endif