Files
aqhomecontrol/avr/common/eeprom_tlv.asm
Martin Preuss 2636fa8b21 fixed apidoc.
2026-01-23 21:40:42 +01:00

143 lines
3.5 KiB
NASM

; ***************************************************************************
; 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. *
; ***************************************************************************
#ifndef AQH_AVR_COMMON_EEPROM_TLV_H
#define AQH_AVR_COMMON_EEPROM_TLV_H
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine EepromTlv_AddTlv @global
;
; @param r16 type (must not be 0xff!)
; @param r17 length
; @return CFLAG set if free bytes found, cleared on error
; @return X EEPROM address of data for TLV (behind TLV header)
; @clobbers R16, R20, R21, X (R18)
EepromTlv_AddTlv:
mov r20, r16
mov r21, r17
ldi r16, 0xff
rcall EepromTlv_FindFirst ; (r16, r17, r18)
brcc EepromTlv_AddTlv_end
cpi r17, 0xff
brne EepromTlv_AddTlv_clcEnd
add xl, r21 ; wanted size
adc xh, r21
sub xh, r21
rcall Eeprom_CheckAddr ; check end address (R16)
brcc EepromTlv_AddTlv_end
sub xl, r21
sbc xh, r21
add xh, r21
sbiw xh:xl, 2 ; go back to begin of TLV
mov r16, r20 ; type
rcall Eeprom_WriteByte ; (R17)
adiw xh:xl, 1
mov r16, r21 ; length
rcall Eeprom_WriteByte ; (R17)
adiw xh:xl, 1
sec
rjmp EepromTlv_AddTlv_end
EepromTlv_AddTlv_clcEnd:
clc
EepromTlv_AddTlv_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine EepromTlv_FindFirst @global
;
; Find first matching TLV
;
; @param r16 TLV type to find
; @return CFLAG set if TLV found, cleared otherwise
; @return r16 type
; @return r17 length
; @return X points to begin of TLV data
; @clobbers r16, r17, r18
EepromTlv_FindFirst:
ldi xl, LOW(EEPROM_OFFS_TLV)
ldi xh, HIGH(EEPROM_OFFS_TLV)
rjmp eepromTlvFind ; (R18)
; @end
; ---------------------------------------------------------------------------
; @routine eepromTlvFind @global
;
; @param r16 TLV type to find
; @param X EEPROM address to start search
; @return CFLAG set if TLV found, cleared otherwise
; @return r16 type
; @return r17 length
; @return X points to begin of TLV data
; @clobbers r16, r17, r18
eepromTlvFind:
mov r18, r16
eepromTlvFind_loop:
rcall EepromTlv_ReadHeader ; r16=type, r17=len (none)
brcc eepromTlvFind_notFound
cp r16, r18 ; the one we wanted?
breq eepromTlvFind_found
add xl, r17 ; skip TLV data
adc xh, r17
sub xh, r17
rjmp eepromTlvFind_loop
eepromTlvFind_notFound:
clc
rjmp eepromTlvFind_end
eepromTlvFind_found:
sec
eepromTlvFind_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine EepromTlv_ReadHeader
;
; @param X EEPROM address
; @return CFLAG set if address okay, cleared if out of range
; @return r16 type
; @return r17 length (only data length, can be 0)
; @return X EEPROM address behind TLV header
; @clobbers none
EepromTlv_ReadHeader:
rcall Eeprom_ReadByte ; read type
brcc EepromTlv_ReadHeader_ret
adiw xh:xl, 1
push r16
rcall Eeprom_ReadByte ; read length
mov r17, r16
pop r16
brcc EepromTlv_ReadHeader_ret
adiw xh:xl, 1
sec
EepromTlv_ReadHeader_ret:
ret
; @end
#endif