; ***************************************************************************
; copyright   : (C) 2026 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_MODULES_EE_25LC256_MAIN_ASM
#define AQH_AVR_MODULES_EE_25LC256_MAIN_ASM



; ***************************************************************************
; defs

.equ EE_25LC256_SIZE        = 32768

.equ EE_25LC256_CMD_READ  = 0x03
.equ EE_25LC256_CMD_WRITE = 0x02
.equ EE_25LC256_CMD_WRDI  = 0x04
.equ EE_25LC256_CMD_WREN  = 0x06
.equ EE_25LC256_CMD_RDSR  = 0x05
.equ EE_25LC256_CMD_WRSR  = 0x01




; ***************************************************************************
; data

.dseg



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

.cseg



; ---------------------------------------------------------------------------
; @routine EE_25LC256_Init @global
;
; @param X destination address

EE_25LC256_Init:
  sbi EEPROMCS_DDR, EEPROMCS_PIN      ; EEPROMCS: output
  sbi EEPROMCS_OUTPUT, EEPROMCS_PIN   ; EEPROMCS high
  sec
  ret
; @end





; ---------------------------------------------------------------------------
; @routine EE_25LC256_StartWriting @global
;
; @param X destination address
; @clobbers r16-r19, r23

EE_25LC256_StartWriting:
  ldi r16, EE_25LC256_CMD_WRITE
  rjmp ee25LC256StartTransfer   ; (r16-r19, r23)
; @end



; ---------------------------------------------------------------------------
; @routine EE_25LC256_StartReading @global
;
; @param X source address
; @clobbers r16-r19, r23

EE_25LC256_StartReading:
  ldi r16, EE_25LC256_CMD_READ
  rjmp ee25LC256StartTransfer   ; (r16-r19, r23)
; @end



; ---------------------------------------------------------------------------
; @routine EE_25LC256_EndTransfer @global
;
; @clobbers none

EE_25LC256_EndTransfer:
  sbi EEPROMCS_OUTPUT, EEPROMCS_PIN     ; CS high
  bigcall SPISW_MasterStop              ; (none)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine EE_25LC256_ReadBytes @global
;
; @param X        source address
; @param Y        destination address
; @param R25:r24  number of bytes to read
; @clobbers r16-r19, r23-r25, Y

EE_25LC256_ReadBytes:
  rcall EE_25LC256_StartReading  ; (r16-r19, r23)
  
EE_25LC256_ReadBytes_loop:
    ldi r16, 0xff
    bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
    st Y+, r16
    sbiw r25:r24, 1
  brne EE_25LC256_ReadBytes_loop
  rcall EE_25LC256_EndTransfer
  ret
; @end



; ---------------------------------------------------------------------------
; @routine EE_25LC256_WriteBytes @global
;
; @param X        destination address
; @param Y        source address
; @param R25:r24  number of bytes to write
; @clobbers r16-r19, r23-r25, Y

EE_25LC256_WriteBytes:
  rcall EE_25LC256_WriteEnable            ; (r16-r19, r23)
  rcall EE_25LC256_StartWriting           ; (r16-r19, r23)
EE_25LC256_WriteBytes_loop:
    ld r16, Y+
    bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
    sbiw r25:r24, 1
  brne EE_25LC256_WriteBytes_loop
  rcall EE_25LC256_EndTransfer            ; (none)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine EE_25LC256_ReadStatusRegister
;
; @return r16 mode register
; @clobbers r17-r19, r23

EE_25LC256_ReadStatusRegister:
  ldi r16, EE_25LC256_CMD_RDSR
  rcall ee25LC256StartCommand
  clr r16
  bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
  push r16
    rcall EE_25LC256_EndTransfer
  pop r16
  ret
; @end



; ---------------------------------------------------------------------------
; @routine EE_25LC256_WriteEnable
;
; @clobbers r16-r19, r23

EE_25LC256_WriteEnable:
  ldi r16, EE_25LC256_CMD_WREN
  rcall ee25LC256StartCommand   ; (r16-r19, r23)
  rcall EE_25LC256_EndTransfer  ; (none)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ee25LC256StartTransfer
;
; @param r16 command
; @param X address
; @clobbers r16-r19, r23

ee25LC256StartTransfer:
  rcall ee25LC256StartCommand

  ; send address
  mov r16, xh
  bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
  mov r16, xl
  bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
  
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ee25LC256StartCommand
;
; @param r16 command
; @clobbers r16-r19, r23

ee25LC256StartCommand:
  push r16
    bigcall SPISW_MasterStart
  pop r16
  nop
  sbi EEPROMCS_DDR, EEPROMCS_PIN      ; CS: output
  cbi EEPROMCS_OUTPUT, EEPROMCS_PIN   ; CS low
  nop
  
  ; send command
  bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)

  ret
; @end





#endif

