; ***************************************************************************
; 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_RAM_23LC512_MAIN_ASM
#define AQH_AVR_MODULES_RAM_23LC512_MAIN_ASM



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

.equ RAM_23LC512_LASTADDR    = 65535
.equ RAM_23LC512_PATTERNSIZE = 0

.equ RAM_23LC512_CMD_READ  = 0x03
.equ RAM_23LC512_CMD_WRITE = 0x02
.equ RAM_23LC512_CMD_RDMR  = 0x05
.equ RAM_23LC512_CMD_WRMR  = 0x01




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

.dseg



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

.cseg



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

RAM_23LC512_Init:
  sbi RAMCS_DDR, RAMCS_PIN      ; RAMCS: output
  sbi RAMCS_OUTPUT, RAMCS_PIN   ; RAMCS high
  sec
  ret
; @end





; ---------------------------------------------------------------------------
; @routine RAM_23LC512_StartWriting @global
;
; @param X destination address
; @clobbers r16, r17, r23

RAM_23LC512_StartWriting:
  ldi r16, RAM_23LC512_CMD_WRITE
  rjmp ram23LC512StartTransfer   ; (r16, r17, r23)
; @end



; ---------------------------------------------------------------------------
; @routine RAM_23LC512_StartReading @global
;
; @param X source address
; @clobbers r16, r17, r23

RAM_23LC512_StartReading:
  ldi r16, RAM_23LC512_CMD_READ
  rjmp ram23LC512StartTransfer   ; (r16, r17, r23)
; @end



; ---------------------------------------------------------------------------
; @routine RAM_23LC512_EndTransfer @global
;
; @clobbers none

RAM_23LC512_EndTransfer:
  sbi RAMCS_OUTPUT, RAMCS_PIN     ; CS high
  bigcall SPISW_MasterStop        ; (none)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RAM_23LC512_ReadBytes @global
;
; @param X        source address
; @param Y        destination address
; @param R17      number of bytes to read
; @clobbers r16, r17, r23

RAM_23LC512_ReadBytes:
  push r22
    mov r22, r17
    rcall RAM_23LC512_StartReading  ; (r16, r17, r23)
  
RAM_23LC512_ReadBytes_loop:
      ldi r16, 0xff
      bigcall SPISW_MasterExchangeByteMode0 ; (r17, r23)
      st Y+, r16
      dec r22
    brne RAM_23LC512_ReadBytes_loop
    rcall RAM_23LC512_EndTransfer
  pop r22
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RAM_23LC512_WriteBytes @global
;
; @param X        destination address
; @param Y        source address
; @param R17      number of bytes to read
; @clobbers r16, r17, r23

RAM_23LC512_WriteBytes:
  push r22
    mov r22, r17
    rcall RAM_23LC512_StartWriting          ; (r16, r17, r23)
  
RAM_23LC512_WriteBytes_loop:
      ld r16, Y+
      bigcall SPISW_MasterExchangeByteMode0 ; (r17, r23)
      dec r22
    brne RAM_23LC512_WriteBytes_loop
    rcall RAM_23LC512_EndTransfer           ; (none)
  pop r22
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RAM_23LC512_Fill @global
;
; @param X        destination address
; @param R16      byte to write
; @param R25:r24  number of bytes to write
; @clobbers r16-r19, r22-r25

RAM_23LC512_Fill:
  mov r22, r16
  rcall RAM_23LC512_StartWriting  ; (r16-r19, r23)
  
RAM_23LC512_Fill_loop:
    mov r16, r22
    bigcall SPISW_MasterExchangeByteMode0 ; (r17, r18, r19, r23)
    sbiw r25:r24, 1
  brne RAM_23LC512_Fill_loop
  rcall RAM_23LC512_EndTransfer
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RAM_23LC512_WritePattern @global
;
; @clobbers r16, r17, r23, X

RAM_23LC512_WritePattern:
  push r24
    push r25
      clr xl
      clr xh
      rcall RAM_23LC512_StartWriting            ; (r16, r17, r23)
      ldi r24, LOW(RAM_23LC512_PATTERNSIZE)
      ldi r25, HIGH(RAM_23LC512_PATTERNSIZE)
RAM_23LC512_WritePattern_loop:
        mov r16, xh
        bigcall SPISW_MasterExchangeByteMode0   ; (r16, r17, r23)
        adiw xh:xl, 1
        sbiw r25:r24, 1
      brne RAM_23LC512_WritePattern_loop
      rcall RAM_23LC512_EndTransfer
    pop r25
  pop r24
  ret
; @end



; ---------------------------------------------------------------------------
; @routine RAM_23LC512_ReadPattern @global
;
; @clobbers r16, r17, r23, X

RAM_23LC512_ReadPattern:
  push r24
    push r25
      clr xl
      clr xh
      rcall RAM_23LC512_StartReading          ; (r16, r17, r23)
      ldi r24, LOW(RAM_23LC512_PATTERNSIZE)
      ldi r25, HIGH(RAM_23LC512_PATTERNSIZE)
RAM_23LC512_ReadPattern_loop:
        ldi r16, 0xff
        bigcall SPISW_MasterExchangeByteMode0 ; r16=value read (r17, r23)
        cp r16, xh
        clc
        brne RAM_23LC512_ReadPattern_ret
        adiw xh:xl, 1
        sbiw r25:r24, 1
      brne RAM_23LC512_ReadPattern_loop
      rcall RAM_23LC512_EndTransfer
      sec
RAM_23LC512_ReadPattern_ret:
    pop r25
  pop r24
  ret
; @end



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

RAM_23LC512_ReadModeRegister:
  ldi r16, RAM_23LC512_CMD_RDMR
  rcall ram23LC512StartCommand          ; (r16, r17, r23)
  clr r16
  bigcall SPISW_MasterExchangeByteMode0 ; r16=value (r17, r23)
  push r16
    rcall RAM_23LC512_EndTransfer
  pop r16
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ram23LC512StartTransfer
;
; @param r16 command
; @param X address
; @clobbers r16, r17, r23

ram23LC512StartTransfer:
  rcall ram23LC512StartCommand          ; (r16, r17, r23)

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



; ---------------------------------------------------------------------------
; @routine ram23LC512StartCommand
;
; @param r16 command
; @clobbers r16, r17, r23

ram23LC512StartCommand:
  push r16
    bigcall SPISW_MasterStart   ; (none)
  pop r16
  nop
  sbi RAMCS_DDR, RAMCS_PIN      ; CS: output
  cbi RAMCS_OUTPUT, RAMCS_PIN   ; CS low
  nop
  
  ; send command
  bigcall SPISW_MasterExchangeByteMode0 ; (r16, r17, r23)

  ret
; @end





#endif

