diff --git a/avr/common/0BUILD b/avr/common/0BUILD index bcc931c..dacfbb9 100644 --- a/avr/common/0BUILD +++ b/avr/common/0BUILD @@ -5,7 +5,9 @@ crc8.asm m_ringbuffer.asm + m_ringbuffer_y.asm ringbuffer.asm + ringbuffer_y.asm shared.asm utils.asm utils_copy_from_flash.asm diff --git a/avr/common/m_ringbuffer.asm b/avr/common/m_ringbuffer.asm index d189f9e..343925a 100644 --- a/avr/common/m_ringbuffer.asm +++ b/avr/common/m_ringbuffer.asm @@ -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 diff --git a/avr/common/m_ringbuffer_y.asm b/avr/common/m_ringbuffer_y.asm new file mode 100644 index 0000000..7a8fa1d --- /dev/null +++ b/avr/common/m_ringbuffer_y.asm @@ -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 + + + + diff --git a/avr/common/ringbuffer_y.asm b/avr/common/ringbuffer_y.asm new file mode 100644 index 0000000..ac56ddc --- /dev/null +++ b/avr/common/ringbuffer_y.asm @@ -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 + + +