; ***************************************************************************
; 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_R_H
#define AQH_AVR_COMMON_EEPROM_R_H


; ***************************************************************************
; code

.cseg



; ---------------------------------------------------------------------------
; @routine Eeprom_ReadByte
;
; Read a byte from EEPROM (see example in ATtiny24/44/84 manual p.19).
;
; @param X EEPROM Address to read from
; @return CFLAG set if address okay, cleared if out of range
; @return R16 byte read
; @clobbers none

Eeprom_ReadByte:
  rcall Eeprom_CheckAddr       ; (R16)
  brcc Eeprom_ReadByte_ret
  push r15
    inr r15, SREG
    cli
    ; wait until EEPROM ready
Eeprom_ReadByte_waitLoop:
.ifdef EEPE
      sbic EECR, EEPE          ; wait for previous write to complete (if any)
.else
      sbic EECR, EEWE          ; wait for previous write to complete (if any)
.endif
    rjmp Eeprom_ReadByte_waitLoop
  ; read from EEPROM
    out EEARH, xh            ; set EEPROM address
    out EEARL, xl
    sbi EECR, EERE           ; start EEPROM read by writing EERE
    in r16, EEDR             ; read data from data register

    outr SREG, r15
  pop r15
  sec
Eeprom_ReadByte_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Eeprom_CheckAddr
;
; @param X EEPROM Address to validate
; @return CFLAG set if address okay, cleared if out of range
; @clobbers r16

Eeprom_CheckAddr:
  mov r16, xl
  subi r16, LOW(EEPROMEND)
  mov r16, xh
  sbci r16, HIGH(EEPROMEND)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Eeprom_ReadBytes
;
; @param X    EEPROM Address to read from
; @param Y    address in SDRAM to write to
; @param R17  number of bytes to copy
; @return CFLAG set if address okay, cleared if out of range
; @return X points to next address
; @clobbers r16, r17, X, Y

Eeprom_ReadBytes:
Eeprom_ReadBytes_loop:
    rcall Eeprom_ReadByte ; r16=byte read (none)
    brcc Eeprom_ReadBytes_done
    st Y+, r16
    adiw xh:xl, 1
    dec r17
  brne Eeprom_ReadBytes_loop
  sec
Eeprom_ReadBytes_done:
  ret
; @end





#endif ; AQH_AVR_COMMON_EEPROM_R_H


