; *************************************************************************** ; 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. * ; *************************************************************************** .equ TTYONUART1_SKIPTIME = 2 .equ TTYONUART1_MSG_INTERVAL = 0 .dseg ttyOnUart1_iface: .byte UART_HW_IFACE_SIZE .cseg ; --------------------------------------------------------------------------- ; @routine TtyOnUart1_Init @global ; ; @clobbers Y (R16, R17, X) TtyOnUart1_Init: ldi yl, LOW(ttyOnUart1_iface) ldi yh, HIGH(ttyOnUart1_iface) rcall UART_HW_Interface_Init ; (R16, R17, X) rcall ttyOnUart1Init ; (R16, R17, X) ldi r16, TTYONUART1_IFACENUM std Y+NET_IFACE_OFFS_IFACENUM, r16 ldi r16, 0xfe std Y+NET_IFACE_OFFS_ADDRESS, r16 ret ; @end ; --------------------------------------------------------------------------- ; @routine TtyOnUart1_Periodically @global ; ; @clobbers R16, Y TtyOnUart1_Periodically: ldi yl, LOW(ttyOnUart1_iface) ldi yh, HIGH(ttyOnUart1_iface) ldd r16, Y+NET_IFACE_OFFS_READTIMER inc r16 breq TtyOnUart1_Periodically_l1 std Y+NET_IFACE_OFFS_READTIMER, r16 TtyOnUart1_Periodically_l1: ldd r16, Y+NET_IFACE_OFFS_WRITETIMER inc r16 breq TtyOnUart1_Periodically_l2 std Y+NET_IFACE_OFFS_WRITETIMER, r16 TtyOnUart1_Periodically_l2: ret ; @end ; --------------------------------------------------------------------------- ; @routine TtyOnUart1_RxCharIsr @global @isr ; ; @clobbers none TtyOnUart1_RxCharIsr: push r15 in r15, SREG push r16 push r17 push r18 push r24 push r25 push xl push xh push yl push yh ldi yl, LOW(ttyOnUart1_iface) ldi yh, HIGH(ttyOnUart1_iface) rcall ttyOnUart1RxCharIsr ; (R16, R17, R18, R24, R25, X) pop yh pop yl pop xh pop xl pop r25 pop r24 pop r18 pop r17 pop r16 out SREG, r15 pop r15 reti ; @end ; --------------------------------------------------------------------------- ; @routine TtyOnUart1_TxUdreIsr @global @isr ; ; @clobbers none TtyOnUart1_TxUdreIsr: push r15 in r15, SREG push r16 push r17 push xl push xh push yl push yh ldi yl, LOW(ttyOnUart1_iface) ldi yh, HIGH(ttyOnUart1_iface) rcall ttyOnUart1TxUdreIsr ; (R16, R17, X) pop yh pop yl pop xh pop xl pop r17 pop r16 out SREG, r15 pop r15 reti ; @end ; --------------------------------------------------------------------------- ; @routine TtyOnUart1_TxCharIsr @global @isr ; ; @clobbers none TtyOnUart1_TxCharIsr: push r15 in r15, SREG push r16 push r17 push r18 push xl push xh push yl push yh ldi yl, LOW(ttyOnUart1_iface) ldi yh, HIGH(ttyOnUart1_iface) rcall ttyOnUart1TxCharIsr ; (R16, R17, R18, X) pop yh pop yl pop xh pop xl pop r18 pop r17 pop r16 out SREG, r15 pop r15 reti ; @end ; --------------------------------------------------------------------------- ; @routine TtyOnUart1_SendBuffer @global ; ; @clobbers R16, R17 TtyOnUart1_SendBuffer: push r15 in r15, SREG cli ldd r17, Y+UART_HW_IFACE_OFFS_WRITEMODE cpi r17, UART_HW_WRITEMODE_IDLE breq TtyOnUart1_SendBuffer_setBuffer out SREG, r15 pop r15 clc ret TtyOnUart1_SendBuffer_setBuffer: rcall UART_HW_Interface_SetWriteBuffer ; (R17) ldi r17, UART_HW_WRITEMODE_WRITING std Y+UART_HW_IFACE_OFFS_WRITEMODE, r17 rcall ttyOnUart1StartTx ; (R16) pop r15 out SREG, r15 sec ret ; @end ; --------------------------------------------------------------------------- ; @routine TtyOnUart1_Run @global ; ; @clobbers all TtyOnUart1_Run: push r15 in r15, SREG cli ldi yl, LOW(ttyOnUart1_iface) ldi yh, HIGH(ttyOnUart1_iface) rcall ttyOnUart1RunWriteModes rcall ttyOnUart1RunReadModes pop r15 out SREG, r15 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunWriteModes ; ; @clobbers all, !Y ttyOnUart1RunWriteModes: ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMODE ; handle write functions cpi r16, UART_HW_WRITEMODE_IDLE breq ttyOnUart1RunWriteIdle cpi r16, UART_HW_WRITEMODE_WRITING breq ttyOnUart1RunWriting cpi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY breq ttyOnUart1RunWaitBufferEmpty cpi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY breq ttyOnUart1RunWriteBufferEmpty ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunWriteIdle ; ; @clobbers ttyOnUart1RunWriteIdle: ldd r16, Y+NET_IFACE_OFFS_WRITETIMER cpi r16, TTYONUART1_MSG_INTERVAL ; wait a bit between messages brcs ttyOnUart1RunWriteIdle_end rcall NET_Interface_GetNextOutgoingMsgNum ; (R17, R18, X) brcc ttyOnUart1RunWriteIdle_end rcall NET_Buffer_Locate ; (R17) rcall TtyOnUart1_SendBuffer ; (R16, R17) ttyOnUart1RunWriteIdle_end: ret ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunWriting ; ; @clobbers ttyOnUart1RunWriting: ; TODO: check for timeout etc. ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunWaitBufferEmpty ; ; @clobbers none ttyOnUart1RunWaitBufferEmpty: ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM ldi r17, 0xff cp r16, r17 breq ttyOnUart1RunWaitBufferEmpty_checkHardware std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r17 rcall NET_Buffer_ReleaseByNum ; (R16, X) ttyOnUart1RunWaitBufferEmpty_checkHardware: lds r16, UCSR1A sbrs r16,TXC1 rjmp ttyOnUart1RunWaitBufferEmpty_checkTimer ; bit still clear, go check timer ldi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY ; bit is set, change mode to WRITEBUFFEREMPTY std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16 rjmp ttyOnUart1RunWaitBufferEmpty_end ttyOnUart1RunWaitBufferEmpty_checkTimer: ldd r16, Y+NET_IFACE_OFFS_WRITETIMER cpi r16, 10 brcs ttyOnUart1RunWaitBufferEmpty_end rcall ttyOnUart1StopTx ; disable transceiver and interrupts (R16) ldi r16, NET_IFACE_OFFS_ERR_COLLISIONS_LOW rcall NET_Interface_IncCounter16 ; (R24, R25) ttyOnUart1RunWaitBufferEmpty_enterIdle: ldi r16, UART_HW_WRITEMODE_IDLE std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16 ttyOnUart1RunWaitBufferEmpty_end: ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunWriteBufferEmpty ; ; @clobbers R16, R17, X (R24, R25) ttyOnUart1RunWriteBufferEmpty: rcall ttyOnUart1StopTx ; disable transceiver and interrupts (R16) ldi r16, UART_HW_WRITEMODE_IDLE std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16 ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW ; increment packets counter rcall NET_Interface_IncCounter16 ; (R24, R25) ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunReadModes ; ; @clobbers all, !Y ttyOnUart1RunReadModes: ldd r16, Y+UART_HW_IFACE_OFFS_READMODE ; handle read functions cpi r16, UART_HW_READMODE_IDLE breq ttyOnUart1RunReadIdle ; (R16, R17, R24, R25, X) cpi r16, UART_HW_READMODE_READING breq ttyOnUart1RunReading ; (none) cpi r16, UART_HW_READMODE_SKIPPING breq ttyOnUart1RunSkipping ; (R16) cpi r16, UART_HW_READMODE_MSGRECEIVED breq ttyOnUart1RunMsgReceived ; (R16, R17, R18, R24, R25) ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunReadIdle ; ; @clobbers R16 (R17, R24, R25, X) ttyOnUart1RunReadIdle: rcall UART_HW_Interface_EnsureReadBuffer ; (R16, R17, R24, R25, X) brcc ttyOnUart1RunReadIdle_noBuf ldi r16, UART_HW_READMODE_READING std Y+UART_HW_IFACE_OFFS_READMODE, r16 rcall ttyOnUart1StartRx ; R16 ret ttyOnUart1RunReadIdle_noBuf: ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW rcall NET_Interface_IncCounter16 ; (R24, R25) ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunReading ; ; @clobbers none ttyOnUart1RunReading: ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunSkipping ; ; @clobbers R16 ttyOnUart1RunSkipping: ldi r17, 0xff ldd r16, Y+UART_HW_IFACE_OFFS_READBUFNUM std Y+UART_HW_IFACE_OFFS_READBUFNUM, r17 cp r16, r17 breq ttyOnUart1RunSkipping_checkTimer rcall NET_Buffer_ReleaseByNum ; (R16, X) ttyOnUart1RunSkipping_checkTimer: ldd r16, Y+NET_IFACE_OFFS_READTIMER cpi r16, TTYONUART1_SKIPTIME brcs ttyOnUart1RunSkipping_end ; leave skip mode (enter idle) ldi r16, UART_HW_READMODE_IDLE std Y+UART_HW_IFACE_OFFS_READMODE, r16 ttyOnUart1RunSkipping_end: ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RunMsgReceived ; ; @clobbers R16 (R17, R18, R24, R25) ttyOnUart1RunMsgReceived: rjmp UART_HW_Interface_HandleMsgReceived ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1Init @global ; ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE) ; @clobbers R16, R17, X ttyOnUart1Init: M_UART_HW_Uart_Init 1 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1StartRx @global ; ; @clobbers R16 ttyOnUart1StartRx: M_UART_HW_Uart_StartRx 1 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1StopRx @global ; ; @clobbers R16 ttyOnUart1StopRx: M_UART_HW_Uart_StopRx 1 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1StartTx @global ; ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE) ; @clobbers R16 ttyOnUart1StartTx: M_UART_HW_Uart_StartTx 1 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1StopTx @global ; ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE) ; @clobbers R16 ttyOnUart1StopTx: M_UART_HW_Uart_StopTx 1 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1RxCharIsr @global ; ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE) ; @clobbers R16 (R17, R18, R24, R25, X) ttyOnUart1RxCharIsr: M_UART_HW_Uart_RxCharFullDuplexIsr 1 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1TxUdreIsr @global ; ; Handler for UDRE1 interrupt called when TX data register is empty. ; ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE) ; @clobbers R16, R17, X ttyOnUart1TxUdreIsr: M_UART_HW_Uart_TxUdreIsr 1 ret ; @end ; --------------------------------------------------------------------------- ; @routine ttyOnUart1TxCharIsr @global ; ; Handler for TXC1 interrupt called when a last byte has been completely sent and ; the data register is empty. ; ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE) ; @clobbers R16 ttyOnUart1TxCharIsr: M_UART_HW_Uart_TxCharIsr 1 ret ; @end