; *************************************************************************** ; copyright : (C) 2023 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. * ; *************************************************************************** ; *************************************************************************** ; code .cseg COM_BUFFER_BEGIN: ; --------------------------------------------------------------------------- ; COM_AllocBufferAndGetXY ; ; IN: ; - nothing ; OUT: ; - CFLAG: set if okay, clear otherwise ; - Y: pointer to buffer ; - X: pointer to data portion of the buffer ; MODIFIED REGS: R16, R17 (R21) COM_AllocBufferAndGetXY: rcall COM_BufferAlloc ; (r16, r17, r21) brcc COM_AllocBufferAndGetXY_error mov xl, yl mov xh, yh adiw xh:xl, COM_BUFFER_OFFS_DATA sec ret COM_AllocBufferAndGetXY_error: ldi xl, LOW(comStatsSendNoBuffer) ldi xh, HIGH(comStatsSendNoBuffer) clc ret ; --------------------------------------------------------------------------- ; COM_BufferAlloc ; ; Allocate a transfer buffer. ; IN: ; - nothing ; OUT: ; - CFLAG: set if okay, clear otherwise ; - Y: pointer to allocated buffer in SRAM ; MODIFIED REGISTERS: r16, r17, r21 COM_BufferAlloc: in r21, SREG ; save global interrupt enable bit from SREG cli lds r17, comRecvBuffersUsed cpi r17, COM_BUFFER_NUM brcc COM_AllocBuffer_error ; no buffer available inc r17 ; increment number of buffers used sts comRecvBuffersUsed, r17 ; store new value lds r16, comRecvBuffersWritePos ; get current write pos mov r17, r16 ; increment for next call inc r17 cpi r17, COM_BUFFER_NUM ; CF set if COM_BUFFER_NUM > R17 brcs COM_AllocBuffer_l1 clr r17 ; wraparound COM_AllocBuffer_l1: sts comRecvBuffersWritePos, r17 ; store new writepos for next caller rcall COM_BufferPosToY ; (R16, R17) clr r17 std y+COM_BUFFER_OFFS_FLAGS, r17 ; preset flags out SREG, r21 ; restore global interrupt enable bit in SREG sec ret COM_AllocBuffer_error: out SREG, r21 clc ret ; --------------------------------------------------------------------------- ; COM_BufferDeallocBack ; ; Release a transfer buffer at the end of the list by decreasing the write pos. ; This releases the last allocated buffer! ; ; IN: ; - nothing ; OUT: ; - CFLAG: set if okay, clear otherwise ; MODIFIED REGISTERS: r16, r17, r21 COM_BufferDeallocBack: in r21, SREG ; save global interrupt enable bit from SREG cli lds r17, comRecvBuffersUsed tst r17 breq COM_BufferDeallocBack_error ; no buffer allocated, nothing to release dec r17 sts comRecvBuffersUsed, r17 ; store new value lds r17, comRecvBuffersWritePos tst r17 ; 0? brne COM_BufferDeallocBack_l1 ; nope go directly decrement r17 ldi r17, COM_BUFFER_NUM ; wrap-around COM_BufferDeallocBack_l1: dec r17 sts comRecvBuffersWritePos, r17 out SREG, r21 sec ret COM_BufferDeallocBack_error: out SREG, r21 clc ret ; --------------------------------------------------------------------------- ; COM_BufferDeallocFront ; ; Release a transfer buffer by increasing the read pos. ; ; IN: ; - nothing ; OUT: ; - CFLAG: set if okay, clear otherwise ; MODIFIED REGISTERS: r16, r17, r21 COM_BufferDeallocFront: in r21, SREG ; save global interrupt enable bit from SREG cli lds r17, comRecvBuffersUsed tst r17 breq COM_BufferDeallocFront_error ; no buffer allocated, nothing to release dec r17 sts comRecvBuffersUsed, r17 ; store new value lds r17, comRecvBuffersReadPos inc r17 cpi r17, COM_BUFFER_NUM brcs COM_BufferDeallocFront_l1 clr r17 ; wrap-around COM_BufferDeallocFront_l1: sts comRecvBuffersReadPos, r17 out SREG, r21 sec ret COM_BufferDeallocFront_error: out SREG, r21 clc ret ; --------------------------------------------------------------------------- ; COM_BufferPosToY ; ; Get a pointer to the SRAM position of the given buffer. ; CAVE: Code must correspond to COM_BUFFER_SIZE!! ; IN: ; - R16: buffer number (starting with 0) ; OUT: ; - Y: pointer to buffer in SRAM ; MODIFIED REGISTERS: R16, R17 COM_BufferPosToY: ; calculate offset clr r17 mov yl, r16 clr yh lsl yl rol yh ; *2 add yl, r16 adc yh, r17 ; *3 lsl yl rol yh ; *6 lsl yl rol yh ; *12 lsl yl rol yh ; *24 ; add base position of buffers ldi r16, LOW(comRecvBuffers) ldi r17, HIGH(comRecvBuffers) add yl, r16 adc yh, r17 ret COM_BUFFER_END: .equ MODULE_SIZE_COM_BUFFER = COM_BUFFER_END-COM_BUFFER_BEGIN