143 lines
3.5 KiB
NASM
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
|
|
|