; *************************************************************************** ; 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 ; --------------------------------------------------------------------------- ; @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 ; (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 brcc EepromTlv_AddTlv_end sub xl, r21 sbc xh, r21 add xh, r21 sbiw xh:xl, 2 mov r16, r20 ; type rcall Eeprom_WriteByte adiw xh:xl, 1 mov r16, r21 ; length rcall Eeprom_WriteByte 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 r18 EepromTlv_FindFirst: ldi xl, LOW(EEPROM_OFFS_TLV) ldi xh, HIGH(EEPROM_OFFS_TLV) rjmp EepromTlv_Find ; @end ; --------------------------------------------------------------------------- ; @routine EepromTlv_Find @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 r18 EepromTlv_Find: mov r18, r16 EepromTlv_Find_loop: rcall EepromTlv_ReadHeader brcc EepromTlv_Find_notFound cpi r16, r18 ; the one we wanted? breq EepromTlv_Find_found add xl, r17 ; skip TLV data adc xh, r17 sub xh, r17 rjmp EepromTlv_Find_loop EepromTlv_Find_notFound: clc rjmp EepromTlv_Find_end EepromTlv_Find_found: sec EepromTlv_Find_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_ReadByteIncr ; read type brcc EepromTlv_ReadHeader adiw xh:xl, 1 push r16 rcall Eeprom_ReadByteIncr ; read length mov r17, r16 pop r16 brcc EepromTlv_ReadHeader adiw xh:xl, 1 sec EepromTlv_ReadHeader: ret ; @end