; *************************************************************************** ; 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. * ; *************************************************************************** ; =========================================================================== ; defs ; =========================================================================== ; code segment .cseg ; --------------------------------------------------------------------------- ; @routine NET_Buffer_Init @global ; ; @clobbers R16, R17, X NET_Buffer_Init: ldi xl, LOW(netBuffers) ldi xh, HIGH(netBuffers) ldi r16, NET_BUFFERS_NUM sts netBuffersFree, r16 clr r16 sts netBuffersMaxUsed, r16 sts netBuffersUsed, r16 m_fixedbuf_init NET_BUFFERS_SIZE, NET_BUFFERS_NUM ret ; @end ; --------------------------------------------------------------------------- ; @routine NET_Buffer_Alloc @global ; ; @return CFLAG set if buffer available, cleared otherwise ; @return r16 buffer num ; @return X pointer to start of buffer ; @clobbers R16, R17, X NET_Buffer_Alloc: push r15 in r15, SREG cli lds r17, netBuffersFree tst r17 breq NET_Buffer_Alloc_error rcall NET_Buffer_Alloc_noIrq brcc NET_Buffer_Alloc_error lds r17, netBuffersFree dec r17 sts netBuffersFree, r17 lds r17, netBuffersUsed inc r17 sts netBuffersUsed, r17 push r16 lds r16, netBuffersMaxUsed cp r16, r17 brcc NET_Buffer_Alloc_countersSet sts netBuffersMaxUsed, r17 NET_Buffer_Alloc_countersSet: #ifdef MODULES_LED_SIGNAL ldi r16, T03_FLAGS_ALLOC rcall LedSignal_ClrFlag ; (R17) #endif pop r16 out SREG, r15 pop r15 sec ret NET_Buffer_Alloc_error: #ifdef MODULES_LED_SIGNAL ldi r16, T03_FLAGS_ALLOC rcall LedSignal_SetFlag ; (R17) #endif out SREG, r15 pop r15 clc ret NET_Buffer_Alloc_noIrq: ldi xl, LOW(netBuffers) ldi xh, HIGH(netBuffers) m_fixedbuf_reserve NET_BUFFERS_SIZE, NET_BUFFERS_NUM brcc NET_Buffer_Alloc_end ldi r17, (1< not in use dec r16 breq NET_Buffer_ReleaseByAddr_release swap r16 push r17 ld r17, X andi r17, 0x0f or r16, r17 st X, r16 pop r17 rjmp NET_Buffer_ReleaseByAddr_done NET_Buffer_ReleaseByAddr_release: m_fixedbuf_release lds r16, netBuffersFree inc r16 sts netBuffersFree, r16 lds r16, netBuffersUsed dec r16 sts netBuffersUsed, r16 NET_Buffer_ReleaseByAddr_done: out SREG, r15 pop r15 ret ; @end ; --------------------------------------------------------------------------- ; @routine NET_Buffer_IncRef @global ; ; @param X pointer to start of buffer ; @clobbers R16 NET_Buffer_IncRef: push r15 in r15, SREG cli ld r16, X swap r16 ; ref counter now in lower nibble andi r16, 0x0f breq NET_Buffer_IncRef_done ; refcounter 0? -> not in use inc r16 breq NET_Buffer_IncRef_done ; don't increment if refcounter at max!!! swap r16 ; ref counter now in high nibble again push r17 ld r17, X andi r17, 0x0f ; clear ref counter in r17 or r16, r17 ; or new ref counter into r17 st X, r16 ; store new header byte pop r17 NET_Buffer_IncRef_done: out SREG, r15 pop r15 ret ; @end ; --------------------------------------------------------------------------- ; @routine NET_Buffer_ReleaseByNum @global ; ; @param r16 buffer number ; @clobbers X (R16) NET_Buffer_ReleaseByNum: push r15 in r15, SREG cli rcall NET_Buffer_Locate ; (R16, X) brcc NET_Buffer_ReleaseByNum_end rcall NET_Buffer_ReleaseByAddr ; (R16) NET_Buffer_ReleaseByNum_end: out SREG, r15 pop r15 ret ; @end ; --------------------------------------------------------------------------- ; @routine NET_Buffer_Locate ; ; Get position of a given buffer. ; ; CAVE: need to change this routine if UART_HW_FIXEDBUFFERS_SIZE is changed! ; ; @return CFLAG set if okay, cleared on error ; @return X points to start of buffer with the given num ; @param r16 buffer num (0-max) ; @clobbers r17 NET_Buffer_Locate: cpi r16, NET_BUFFERS_NUM brcc NET_Buffer_Locate_end ; out of range .if NET_BUFFERS_SIZE == 32 mov xh, r16 ; * 256 clr xl lsr xh ; *128 ror xl lsr xh ; *64 ror xl lsr xh ; *32 ror xl .elif NET_BUFFERS_SIZE == 28 clr r17 mov xl, r16 ; * 256 clr xh lsl xl ; * 2 rol xh add xl, r16 ; * 3 adc xh, r17 lsl xl ; * 6 rol xh add xl, r16 ; * 7 adc xh, r17 lsl xl ; * 14 rol xh lsl xl ; * 28 rol xh .else .error "Unhandled buffer size" .endif ldi r17, LOW(netBuffers) add xl, r17 ldi r17, HIGH(netBuffers) adc xh, r17 sec NET_Buffer_Locate_end: ret ; @end ; --------------------------------------------------------------------------- ; @routine NET_Buffer_CountUsed ; ; @return r16 number of buffers in use ; @param X pointer to start of buffers ; @param %0 constant maxBytes per buffer (including statusbyte in front) ; @param %1 constant maxBuffers ; @clobbers r16, r17, r18, X NET_Buffer_CountUsed: ldi xl, LOW(netBuffers) ldi xh, HIGH(netBuffers) m_fixedbuf_count_used NET_BUFFERS_SIZE, NET_BUFFERS_NUM ret ; @end