avr: added uart_bitbang module.
Started reorganizing COM module by splitting into higher and lower level functions.
This commit is contained in:
398
avr/modules/uart_bitbang/main.asm
Normal file
398
avr/modules/uart_bitbang/main.asm
Normal file
@@ -0,0 +1,398 @@
|
||||
; ***************************************************************************
|
||||
; copyright : (C) 2024 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. *
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
|
||||
; UART_BitBang_Init
|
||||
; UART_BitBang_Fini
|
||||
; UART_BitBang_Run
|
||||
; UART_BitBang_SendPacket:
|
||||
; UART_BitBang_GetNextReceivedPacket:
|
||||
; UART_BitBang_ReleaseReceivedPacket:
|
||||
|
||||
|
||||
.include "modules/com2/buffer.asm"
|
||||
|
||||
|
||||
|
||||
.dseg
|
||||
|
||||
|
||||
uartBitbangDataBegin:
|
||||
uartBitbangRecvBuffersUsed: .byte 1
|
||||
uartBitbangMaxBuffersUsed: .byte 1
|
||||
uartBitbangRecvBuffersWritePos: .byte 1
|
||||
uartBitbangRecvBuffersReadPos: .byte 1
|
||||
uartBitbangRecvBuffers: .byte COM2_BUFFER_SIZE*UART_BITBANG_BUFFER_NUM
|
||||
uartBitbangDataEnd:
|
||||
|
||||
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_Init
|
||||
;
|
||||
; @return CFLAG set if okay, clear on error
|
||||
; @clobbers R16, R17, X, Y
|
||||
|
||||
UART_BitBang_Init:
|
||||
; preset SRAM data area
|
||||
ldi xh, HIGH(uartBitbangDataBegin)
|
||||
ldi xl, LOW(uartBitbangDataBegin)
|
||||
clr r16
|
||||
ldi r17, (uartBitbangDataEnd-uartBitbangDataBegin)
|
||||
rcall Utils_FillSram
|
||||
|
||||
; setup pins and interrupts
|
||||
cbi COM_TXD_DATA, COM_TXD_PIN ; disable internal pullup for TXD
|
||||
cbi COM_TXD_DDR, COM_TXD_PIN ; set TXD port as input
|
||||
|
||||
cbi COM_RXD_DATA, COM_RXD_PIN ; disable internal pullup for RXD
|
||||
cbi COM_RXD_DDR, COM_RXD_PIN ; set RXD port as input
|
||||
|
||||
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
|
||||
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
|
||||
|
||||
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_Init
|
||||
;
|
||||
; @return CFLAG set if okay, clear on error
|
||||
; @clobbers R16, R17, X, Y
|
||||
|
||||
UART_BitBang_Fini:
|
||||
cbi COM_TXD_DDR, COM_TXD_PIN ; set TXD port as input
|
||||
cbi COM_RXD_DDR, COM_RXD_PIN ; set RXD 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_Run
|
||||
;
|
||||
; @clobbers any
|
||||
|
||||
UART_BitBang_Run:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_SendPacket
|
||||
; Send packet, if line free.
|
||||
;
|
||||
; @param X buffer to send
|
||||
; @return CFLAG: set if okay (packet sent), cleared on error
|
||||
; @clobbers r22, x (r18, r19, r22)
|
||||
|
||||
UART_BitBang_SendPacket:
|
||||
rcall uartBitbang_SendPacket
|
||||
brcs UART_BitBang_SendPacket_okay
|
||||
cpi r16, COM2_ERROR_BUSY
|
||||
breq UART_BitBang_SendPacket_busyError
|
||||
cpi r16, COM2_ERROR_COLLISION
|
||||
breq UART_BitBang_SendPacket_collError
|
||||
; fall-through
|
||||
UART_BitBang_SendPacket_busyError:
|
||||
ldi xl, LOW(com2StatsBusyError)
|
||||
ldi xh, HIGH(com2StatsBusyError)
|
||||
rjmp UART_BitBang_SendPacket_incCounterRetNc
|
||||
UART_BitBang_SendPacket_collError:
|
||||
ldi xl, LOW(com2StatsCollisions)
|
||||
ldi xh, HIGH(com2StatsCollisions)
|
||||
UART_BitBang_SendPacket_incCounterRetNc:
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, r22)
|
||||
clc
|
||||
ret
|
||||
UART_BitBang_SendPacket_okay:
|
||||
ldi xl, LOW(com2StatsPacketsOut)
|
||||
ldi xh, HIGH(com2StatsPacketsOut)
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, r22)
|
||||
sec
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_GetNextReceivedPacket
|
||||
;
|
||||
; Get next received packet from receiption buffers.
|
||||
; Call @ref UART_BitBang_ReleaseReceivedPacket to release the packet buffer.
|
||||
;
|
||||
; @return CFLAG set if okay (packet received), cleared on error
|
||||
; @return X pointer to packet received
|
||||
; @clobbers r16, r17
|
||||
|
||||
UART_BitBang_GetNextReceivedPacket:
|
||||
lds r16, uartBitbangRecvBuffersUsed
|
||||
tst r16
|
||||
breq UART_BitBang_GetNextReceivedPacket_retNc ; no buffers in use
|
||||
lds r16, uartBitbangRecvBuffersReadPos
|
||||
rcall uartBitbang_BufferPosToX ; get current read buffer to X (R16, R17)
|
||||
sec
|
||||
ret
|
||||
UART_BitBang_GetNextReceivedPacket_retNc:
|
||||
clc
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_BitBang_ReleaseReceivedPacket
|
||||
;
|
||||
; Release first packet in queue from from receiption buffers (i.e. the one returned
|
||||
; by @ref UART_BitBang_GetNextReceivedPacket)
|
||||
;
|
||||
; @clobbers r16, r17, r21
|
||||
|
||||
UART_BitBang_ReleaseReceivedPacket:
|
||||
rjmp COM2_BufferDeallocFront ; (r16, r17, r21)
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitbang_ReceivePacket
|
||||
;
|
||||
; Receive packet.
|
||||
;
|
||||
; @return CFLAG set if okay (packet received), cleared on error
|
||||
; @clobbers r16, r17, x (r18, r19, r20, r21, r22)
|
||||
|
||||
uartBitbang_ReceivePacket:
|
||||
rcall uartBitbang_BufferAlloc ; (r16, r17, r21)
|
||||
brcs uartBitbang_ReceivePacket_bufferAvailable
|
||||
|
||||
ldi xl, LOW(com2StatsNoBufferError) ; buffer in use, don't release
|
||||
ldi xh, HIGH(com2StatsNoBufferError) ; just increment error counter
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
clc
|
||||
ret
|
||||
uartBitbang_ReceivePacket_bufferAvailable:
|
||||
push xl
|
||||
push xh
|
||||
lds r16, com2Address
|
||||
ldi r17, (COM2_BUFFER_SIZE-3) ; buffer size minus dst addr, payload len, crc byte
|
||||
rcall uartBitbang_ReceivePacketIntoBuffer ; r16, r17, r18, X (r19, r20, r21, r22)
|
||||
pop xh
|
||||
pop xl
|
||||
brcc uartBitbang_ReceivePacket_error
|
||||
|
||||
rcall com2CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
||||
brcc uartBitbang_ReceivePacket_dataError
|
||||
|
||||
; everything okay
|
||||
ldi xl, LOW(com2StatsPacketsIn)
|
||||
ldi xh, HIGH(com2StatsPacketsIn)
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
sec
|
||||
ret
|
||||
|
||||
uartBitbang_ReceivePacket_error:
|
||||
cpi r16, COM2_ERROR_NOTFORME
|
||||
breq uartBitbang_ReceivePacket_notForMe
|
||||
cpi r16, COM2_ERROR_DATAERROR
|
||||
breq uartBitbang_ReceivePacket_dataError
|
||||
;cpi r16, COM2_ERROR_IOERROR
|
||||
;breq uartBitbang_ReceivePacket_ioError
|
||||
;rjmp uartBitbang_ReceivePacket_retnc
|
||||
rjmp uartBitbang_ReceivePacket_ioError ; default to IO ERROR
|
||||
uartBitbang_ReceivePacket_ioError:
|
||||
ldi xl, LOW(com2StatsIoError)
|
||||
ldi xh, HIGH(com2StatsIoError)
|
||||
rjmp uartBitbang_ReceivePacket_incCounterDeallocNc
|
||||
uartBitbang_ReceivePacket_dataError:
|
||||
ldi xl, LOW(com2StatsContentError)
|
||||
ldi xh, HIGH(com2StatsContentError)
|
||||
rjmp uartBitbang_ReceivePacket_incCounterDeallocNc
|
||||
uartBitbang_ReceivePacket_notForMe:
|
||||
ldi xl, LOW(com2StatsNotForMe)
|
||||
ldi xh, HIGH(com2StatsNotForMe)
|
||||
rjmp uartBitbang_ReceivePacket_incCounterDeallocNc
|
||||
uartBitbang_ReceivePacket_incCounterDeallocNc:
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
uartBitbang_ReceivePacket_deallocRetnc:
|
||||
rcall uartBitbang_BufferDeallocBack
|
||||
uartBitbang_ReceivePacket_retnc:
|
||||
clc
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; Buffer Management
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitbang_BufferAlloc
|
||||
;
|
||||
; Allocate a transfer buffer.
|
||||
;
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @return X pointer to allocated buffer in SRAM
|
||||
; @clobbers r16, r17, r21
|
||||
|
||||
uartBitbang_BufferAlloc:
|
||||
COM2_M_BufferAlloc UART_BITBANG_BUFFER_NUM, uartBitbangMaxBuffersUsed, uartBitbangRecvBuffersUsed, uartBitbangRecvBuffersWritePos
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitbang_BufferDeallocBack
|
||||
;
|
||||
; Release a transfer buffer at the end of the list by decreasing the write pos.
|
||||
; This releases the last allocated buffer!
|
||||
;
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @clobbers r16, r17, r21
|
||||
|
||||
uartBitbang_BufferDeallocBack:
|
||||
COM2_M_BufferDeallocBack UART_BITBANG_BUFFER_NUM, uartBitbangRecvBuffersUsed, uartBitbangRecvBuffersWritePos
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitbang_BufferDeallocFront
|
||||
;
|
||||
; Release a transfer buffer by increasing the read pos.
|
||||
;
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @clobbers r16, r17, r21
|
||||
|
||||
uartBitbang_BufferDeallocFront:
|
||||
COM2_M_BufferDeallocFront UART_BITBANG_BUFFER_NUM, uartBitbangRecvBuffersUsed, uartBitbangRecvBuffersReadPos
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartBitbang_BufferPosToX
|
||||
;
|
||||
; Get a pointer to the SRAM position of the given buffer.
|
||||
; CAVE: Code must correspond to COM2_BUFFER_SIZE!!
|
||||
;
|
||||
; @param R16 buffer number (starting with 0)
|
||||
; @return X pointer to buffer in SRAM
|
||||
; @clobbers R16, R17
|
||||
|
||||
uartBitbang_BufferPosToX:
|
||||
COM2_M_BufferPosToX uartBitbangRecvBuffers
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; ISR
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
uartBitbangIsrPcint0:
|
||||
push r15
|
||||
in r15, SREG
|
||||
sbic COM_ATTN_INPUT, COM_ATTN_PIN
|
||||
rjmp uartBitbangIsrPcint0_end
|
||||
; low, read packet
|
||||
push r1
|
||||
push r16
|
||||
push r17
|
||||
push r18
|
||||
push r19
|
||||
push r20
|
||||
push r21
|
||||
push r22
|
||||
push xh
|
||||
push xl
|
||||
push r15
|
||||
rcall uartBitbang_ReceivePacket ; (r16, r17, r18, r19, r20, r21, r22, x)
|
||||
pop r15
|
||||
lds xl, com2Interrupts
|
||||
lds xh, com2Interrupts+1
|
||||
adiw xh:xl, 1
|
||||
sts com2Interrupts, xl
|
||||
sts com2Interrupts+1, xh
|
||||
pop xl
|
||||
pop xh
|
||||
pop r22
|
||||
pop r21
|
||||
pop r20
|
||||
pop r19
|
||||
pop r18
|
||||
pop r17
|
||||
pop r16
|
||||
pop r1
|
||||
uartBitbangIsrPcint0_end:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
|
||||
|
||||
|
||||
; set routine functions
|
||||
.equ COMIO_Init = UART_BitBang_Init
|
||||
.equ COMIO_Fini = UART_BitBang_Fini
|
||||
.equ COMIO_Run = UART_BitBang_Run
|
||||
.equ COMIO_SendPacket = UART_BitBang_SendPacket
|
||||
.equ COMIO_GetNextReceivedPacket = UART_BitBang_GetNextReceivedPacket
|
||||
.equ COMIO_ReleaseReceivedPacket = UART_BitBang_ReleaseReceivedPacket
|
||||
|
||||
|
||||
Reference in New Issue
Block a user