avr: more ringbuffer macros and code.

This commit is contained in:
Martin Preuss
2025-01-16 17:04:18 +01:00
parent fff64ae41e
commit 87706e1265
4 changed files with 245 additions and 40 deletions

View File

@@ -5,7 +5,9 @@
<extradist>
crc8.asm
m_ringbuffer.asm
m_ringbuffer_y.asm
ringbuffer.asm
ringbuffer_y.asm
shared.asm
utils.asm
utils_copy_from_flash.asm

View File

@@ -10,38 +10,36 @@
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_writebyte
; @macro m_ringbuffer_writebyte
;
; @param R16 byte to write
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 constant maxBytes
; @param %1 offset to Y to access usedBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @param %1 address of usedBytes variable
; @param %2 address of readPos variable
; @param %3 address of writePos variable
; @param %4 address of buffer
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @clobbers R17, X
.macro m_ringbuffer_y_writebyte
ldd r17, Y+@1 ; usedBytes
cpi r17, @0 ; maxBytes
.macro m_ringbuffer_writebyte
ld r17, @1 ; usedBytes
cpi r17, @0 ; maxBytes
brcc l_end
inc r17
std Y+@1, r17 ; usedBytes
ldd r17, Y+@3 ; writePos
mov xl, yl
mov xh, yh
adiw xh:xl, @4
st @1, r17 ; usedBytes
ld r17, @3 ; writePos
ldi xl, LOW(@4) ; buffer start
ldi xh, HIGH(@4)
add xl, r17
adc xh, r17
sub xh, r17
st X, r16
inc r17
cpi r17, @0
cpi r17, @0 ; maxBytes
brcs l_store
clr r17
l_store:
std Y+@3, r17 ; writePos
st @3, r17 ; writePos
sec
l_end:
.endmacro
@@ -50,29 +48,27 @@ l_end:
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_readbyte
; @macro m_ringbuffer_readbyte
;
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 constant maxBytes
; @param %1 offset to Y to access usedBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @param %1 address of usedBytes variable
; @param %2 address of readPos variable
; @param %3 address of writePos variable
; @param %4 address of buffer
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @return R16 byte read
; @clobbers R17, X
.macro m_ringbuffer_y_readbyte
ldd r17, Y+@1 ; usedBytes
.macro m_ringbuffer_readbyte
ld r17, @1 ; usedBytes
tst r17
clc
breq l_end
dec r17
std Y+@1, r17 ; usedBytes
ldd r17, Y+@2 ; readPos
mov xl, yl
mov xh, yh
adiw xh:xl, @4
st @1, r17 ; usedBytes
ld r17, @2 ; readPos
ldi xl, LOW(@4) ; buffer start
ldi xh, HIGH(@4)
add xl, r17
adc xh, r17
sub xh, r17
@@ -82,7 +78,7 @@ l_end:
brcs l_store
clr r17
l_store:
std Y+@2, r17 ; readPos
st @2, r17 ; readPos
sec
l_end:
.endmacro
@@ -90,21 +86,20 @@ l_end:
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_reset
; @macro m_ringbuffer_reset
;
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 constant maxBytes
; @param %1 offset to Y to access usedBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @param %1 address of usedBytes variable
; @param %2 address of readPos variable
; @param %3 address of writePos variable
; @param %4 address of buffer
; @clobbers R17
.macro m_ringbuffer_y_reset
.macro m_ringbuffer_reset
clr r17
std Y+@1, r17 ; usedBytes
std Y+@2, r17 ; readPos
std Y+@3, r17 ; writePos
st @1, r17 ; usedBytes
st @2, r17 ; readPos
st @3, r17 ; writePos
l_end:
.endmacro
; @end

View File

@@ -0,0 +1,117 @@
; ***************************************************************************
; 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. *
; ***************************************************************************
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_writebyte
;
; @param R16 byte to write
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 offset to Y to access maxBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %1 offset to Y to access usedBytes
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @clobbers R17, R18, X
.macro m_ringbuffer_y_writebyte
ldd r18, Y+@0 ; maxBytes
ldd r17, Y+@1 ; usedBytes
cp r17, r18
brcc l_end ; out-of-range
inc r17
std Y+@1, r17 ; usedBytes
ldd r17, Y+@3 ; writePos
mov xl, yl
mov xh, yh
adiw xh:xl, @4
add xl, r17
adc xh, r17
sub xh, r17
st X, r16
inc r17
cp r17, r18
brcs l_store
clr r17
l_store:
std Y+@3, r17 ; writePos
sec
l_end:
.endmacro
; @end
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_readbyte
;
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 offset to Y to access maxBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %1 offset to Y to access usedBytes
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @return R16 byte read
; @clobbers R17, R18, X
.macro m_ringbuffer_y_readbyte
ldd r18, Y+@0 ; maxBytes
ldd r17, Y+@1 ; usedBytes
tst r17
clc
breq l_end
dec r17
std Y+@1, r17 ; usedBytes
ldd r17, Y+@2 ; readPos
mov xl, yl
mov xh, yh
adiw xh:xl, @4
add xl, r17
adc xh, r17
sub xh, r17
ld r16, X
inc r17
cp r17, r18
brcs l_store
clr r17 ; wrap-around
l_store:
std Y+@2, r17 ; readPos
sec
l_end:
.endmacro
; @end
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_reset
;
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
; @param %0 offset to Y to access maxBytes variable (for "LDD Y+nn" and "STD Y+nn")
; @param %1 offset to Y to access usedBytes
; @param %2 offset to Y to access readPos variable
; @param %3 offset to Y to access writePos variable
; @param %4 offset to Y to access buffer
; @clobbers R17
.macro m_ringbuffer_y_reset
clr r17
std Y+@1, r17 ; usedBytes
std Y+@2, r17 ; readPos
std Y+@3, r17 ; writePos
l_end:
.endmacro
; @end

View File

@@ -0,0 +1,91 @@
; ***************************************************************************
; 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 RINGBUFFERY_OFFS_MAXSIZE = 0
.equ RINGBUFFERY_OFFS_USED = 1
.equ RINGBUFFERY_OFFS_READPOS = 2
.equ RINGBUFFERY_OFFS_WRITEPOS = 3
.equ RINGBUFFERY_OFFS_DATA = 4
; ---------------------------------------------------------------------------
; @routine RingBufferY_Init
;
; @param R16 size of ringbuffer
; @param Y base address of ringbuffer struct
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @clobbers R17
RingBufferY_Init:
std Y+RINGBUFFERY_OFFS_MAXSIZE, r16
rjmp RingBufferY_Reset
; @end
; ---------------------------------------------------------------------------
; @routine RingBufferY_WriteByte
;
; @param R16 byte to write
; @param Y base address of ringbuffer struct
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
; @clobbers R17, R18, X
RingBufferY_WriteByte:
m_ringbuffer_y_writebyte \
RINGBUFFERY_OFFS_MAXSIZE, \
RINGBUFFERY_OFFS_USED, \
RINGBUFFERY_OFFS_READPOS, \
RINGBUFFERY_OFFS_WRITEPOS, \
RINGBUFFERY_OFFS_DATA
ret
; @end
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_readbyte
;
; @param Y base address of ringbuffer struct
; @return CFLAG set if okay, cleared on error (i.e. buffer empty)
; @return R16 byte read
; @clobbers R17, R18, X
RingBufferY_ReadByte:
m_ringbuffer_y_readbyte \
RINGBUFFERY_OFFS_MAXSIZE, \
RINGBUFFERY_OFFS_USED, \
RINGBUFFERY_OFFS_READPOS, \
RINGBUFFERY_OFFS_WRITEPOS, \
RINGBUFFERY_OFFS_DATA
ret
; @end
; ---------------------------------------------------------------------------
; @macro m_ringbuffer_y_reset
;
; @param Y base address of ringbuffer struct
; @clobbers R17
RingBufferY_Reset:
m_ringbuffer_y_reset \
RINGBUFFERY_OFFS_MAXSIZE, \
RINGBUFFERY_OFFS_USED, \
RINGBUFFERY_OFFS_READPOS, \
RINGBUFFERY_OFFS_WRITEPOS, \
RINGBUFFERY_OFFS_DATA
ret
; @end