added uart_bitbang2.
This commit is contained in:
274
avr/modules/uart_bitbang2/iface.asm
Normal file
274
avr/modules/uart_bitbang2/iface.asm
Normal file
@@ -0,0 +1,274 @@
|
||||
; ***************************************************************************
|
||||
; 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 UART_BITBANG_IFACE_H
|
||||
#define UART_BITBANG_IFACE_H
|
||||
|
||||
; ***************************************************************************
|
||||
; includes
|
||||
|
||||
.include "modules/uart_bitbang2/defs.asm"
|
||||
.include "modules/uart_bitbang2/lowlevel.asm"
|
||||
|
||||
.include "modules/network/iface.asm"
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; data
|
||||
|
||||
.dseg
|
||||
|
||||
uart_bitbang_iface: .byte NET_IFACE_SIZE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_Init @global
|
||||
;
|
||||
; @return CFLAG set if okay, clear on error
|
||||
; @clobbers R16, R17, X, Y
|
||||
|
||||
UART_BitBang_Init:
|
||||
ldi yl, LOW(uart_bitbang_iface)
|
||||
ldi yh, HIGH(uart_bitbang_iface)
|
||||
rcall NET_Interface_Init ; (R16, R17, X)
|
||||
|
||||
; init hw
|
||||
sbi COM_IRQ_ADDR_ATTN, COM_IRQ_BIT_ATTN ; enable pin change irq for ATTN line
|
||||
in r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
ori r16, (1<<COM_IRQ_GIMSK_ATTN)
|
||||
out GIMSK, R16
|
||||
ldi r16, (1<<COM_IRQ_GIFR_ATTN) ; clear pending irq by writing 1 to ATTN bit
|
||||
out GIFR, r16
|
||||
|
||||
sec
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_Fini
|
||||
;
|
||||
; @return CFLAG set if okay, clear on error
|
||||
; @clobbers R16, Y
|
||||
|
||||
UART_BitBang_Fini:
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set TXD port as input
|
||||
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
|
||||
|
||||
cbi COM_IRQ_ADDR_ATTN, COM_IRQ_BIT_ATTN ; disable pin change irq for ATTN line
|
||||
in r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
andi r16, ~(1<<COM_IRQ_GIMSK_ATTN)
|
||||
out GIMSK, R16
|
||||
|
||||
ldi r16, (1<<COM_IRQ_GIFR_ATTN) ; clear pending irq by writing 1 to ATTN bit
|
||||
out GIFR, r16
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_Every100ms @global
|
||||
;
|
||||
; Routine doing periodical stuff (like sending outbound mesages)
|
||||
;
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers R16 (R17, R18, R21, R22, R24, R25, X)
|
||||
|
||||
UART_BitBang_Every100ms:
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
rcall NET_Interface_Periodically ; (R16)
|
||||
rcall uartBitBang_sendNextPkg ; (R16, R17, R18, R21, R22, R24, R25, X)
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitBang_sendNextPkg @global
|
||||
;
|
||||
; Check whether there is an outgoing message in interface data
|
||||
; and send it if possible.
|
||||
;
|
||||
; @return CFLAG set if okay, clear on error
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers R16 (R17, R18, R21, R22, R24, R25, X)
|
||||
|
||||
uartBitBang_sendNextPkg:
|
||||
rcall NET_Interface_PeekNextOutgoingMsgNum ; (R17, R18, X)
|
||||
brcc uartBitBang_sendNextPkg_end
|
||||
rcall NET_Buffer_Locate ; get pointer to buffer (R17)
|
||||
brcc uartBitBang_sendNextPkg_end
|
||||
adiw xh:xl, 1 ; skip buffer header
|
||||
rcall uartBitbang_SendPacket ; (R16, R17, R21, R22, X)
|
||||
brcc uartBitBang_sendNextPkg_error
|
||||
rcall NET_Interface_GetNextOutgoingMsgNum ; remove from stack (R17, R18, X)
|
||||
rcall NET_Buffer_ReleaseByNum ; release buffer (R16, X)
|
||||
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
sec
|
||||
rjmp uartBitBang_sendNextPkg_end
|
||||
uartBitBang_sendNextPkg_error:
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
uartBitBang_sendNextPkg_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitbang_receiveNextPkg
|
||||
;
|
||||
; Receive packet.
|
||||
;
|
||||
; @return CFLAG set if okay (packet received), cleared on error
|
||||
; @clobbers R16, R17, X (R18, R19, R20, R21, R22, R24, R25)
|
||||
|
||||
uartBitbang_receiveNextPkg:
|
||||
rcall NET_Buffer_Alloc ; (R16, R17, X)
|
||||
brcs uartBitbang_receiveNextPkg_gotBuffer
|
||||
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
clc
|
||||
rjmp uartBitbang_receiveNextPkg_end
|
||||
uartBitbang_receiveNextPkg_gotBuffer:
|
||||
push r16 ; buffer number
|
||||
adiw xh:xl, 1
|
||||
rcall uartBitbang_receiveAndCheckPkg ; (r16, r17, r18, r19, r20, r21, r22, X)
|
||||
pop r17 ; pop buffer number to R17
|
||||
brcs uartBitbang_receiveNextPkg_gotPkg
|
||||
tst r16 ; error code=0: pkg not for me
|
||||
breq uartBitbang_receiveNextPkg_RelBuffer
|
||||
uartBitbang_receiveNextPkg_incCntRelBuffer:
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
uartBitbang_receiveNextPkg_RelBuffer:
|
||||
mov r16, r17
|
||||
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
||||
clc
|
||||
rjmp uartBitbang_receiveNextPkg_end
|
||||
uartBitbang_receiveNextPkg_gotPkg:
|
||||
mov r16, r17
|
||||
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
|
||||
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
||||
brcc uartBitbang_receiveNextPkg_incCntRelBuffer
|
||||
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
sec
|
||||
uartBitbang_receiveNextPkg_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitbang_receiveAndCheckPkg
|
||||
;
|
||||
; Receive a packet into buffer pointed to by X and CRC check it.
|
||||
; Expects interrupts to be disabled.
|
||||
;
|
||||
; @param X buffer to receive to
|
||||
; @param Y pointer to start of interface data
|
||||
; @return CFLAG set if okay (packet received), cleared on error
|
||||
; @return R16 error var offset if CFLAG is cleared
|
||||
; @clobbers: r16 (r17, r18, r19, r20, r21, r22, X)
|
||||
|
||||
uartBitbang_receiveAndCheckPkg:
|
||||
ldd r16, Y+NET_IFACE_OFFS_ADDRESS
|
||||
ldi r17, (NET_BUFFERS_SIZE-2)
|
||||
push xl
|
||||
push xh
|
||||
rcall uartBitbang_ReceivePacketIntoBuffer ; (r16, r17, r18, r19, r20, r21, r22, X)
|
||||
pop xh
|
||||
pop xl
|
||||
brcc uartBitbang_receiveAndCheckPkg_end
|
||||
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
||||
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
||||
uartBitbang_receiveAndCheckPkg_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; ISR
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_PcintIsr @global @isr
|
||||
;
|
||||
; ISR for PCINT0/1
|
||||
;
|
||||
; @clobbers: none
|
||||
|
||||
UART_BitBang_PcintIsr:
|
||||
push r15
|
||||
in r15, SREG
|
||||
sbic COM_ATTN_INPUT, COM_ATTN_PIN
|
||||
rjmp uartBitbangPcintIsr_end
|
||||
; low, read packet
|
||||
push r16
|
||||
push r17
|
||||
push r18
|
||||
push r19
|
||||
push r20
|
||||
push r21
|
||||
push r22
|
||||
push r24
|
||||
push r25
|
||||
push xl
|
||||
push xh
|
||||
push yl
|
||||
push yh
|
||||
ldi yl, LOW(uart_bitbang_iface)
|
||||
ldi yh, HIGH(uart_bitbang_iface)
|
||||
rcall uartBitbang_receiveNextPkg ; (R16, R17, R18, R19, R20, R21, R22, R24, R25, X)
|
||||
pop yh
|
||||
pop yl
|
||||
pop xh
|
||||
pop xl
|
||||
pop r25
|
||||
pop r24
|
||||
pop r22
|
||||
pop r21
|
||||
pop r20
|
||||
pop r19
|
||||
pop r18
|
||||
pop r17
|
||||
pop r16
|
||||
uartBitbangPcintIsr_end:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
#endif ; UART_BITBANG_IFACE_H
|
||||
|
||||
Reference in New Issue
Block a user