203 lines
4.9 KiB
NASM
203 lines
4.9 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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
; ***************************************************************************
|
|
; defines
|
|
|
|
.equ SPIHW_MODE_SPEED0_BIT = 0 ; 00=CLK/4, 01=CLK/16
|
|
.equ SPIHW_MODE_SPEED1_BIT = 1 ; 10=CLK/64, 11=CLK/128
|
|
.equ SPIHW_MODE_DOUBLESPEED_BIT = 2 ; 1=double speed from SPIHW_MODE_SPEED0/1_BIT
|
|
.equ SPIHW_MODE_DATAORDER_BIT = 3 ; 1=LSB first, 0=MSB first
|
|
.equ SPIHW_MODE_CPOL_BIT = 4 ; 0=leading edge rising/trailing edge falling
|
|
.equ SPIHW_MODE_CPHA_BIT = 5 ; 0=sample on leading edge, setup on trailing edge
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; data
|
|
|
|
.dseg
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine SPIHW_Init @global
|
|
;
|
|
|
|
SPIHW_Init:
|
|
sbi SPIHW_SS0_DDR, SPIHW_SS0_PIN ; SS0= output
|
|
sbi SPIHW_SS1_DDR, SPIHW_SS1_PIN ; SS1= output
|
|
sbi SPIHW_SS2_DDR, SPIHW_SS2_PIN ; SS2= output
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine SPIHW_Fini @global
|
|
;
|
|
|
|
SPIHW_Fini:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine SPIHW_MasterStart @global
|
|
;
|
|
; Start SPI hardware master with the given mode (see @ref SPIHW_MODE_SPEED0_BIT
|
|
; and others).
|
|
|
|
; @param r16 mode
|
|
; @param r17 device num (0-7)
|
|
; @clobbers r17
|
|
|
|
SPIHW_MasterStart:
|
|
; setup pins
|
|
sbi SPIHW_SS_DDR, SPIHW_SS_PIN ; SS : output
|
|
sbi SPIHW_MOSI_DDR, SPIHW_MOSI_PIN ; MOSI: output
|
|
cbi SPIHW_MISO_DDR, SPIHW_MISO_PIN ; MISO: input
|
|
sbi SPIHW_SCK_DDR, SPIHW_SCK_PIN ; SCK: output
|
|
|
|
; select device
|
|
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
|
|
rcall spiHwSelectDevice ; (none)
|
|
; cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
|
|
|
|
; setup SPCR
|
|
clr r17
|
|
sbrc r16, SPIHW_MODE_DATAORDER_BIT
|
|
sbr r17, (1<<DORD)
|
|
sbrc r16, SPIHW_MODE_CPOL_BIT
|
|
sbr r17, (1<<CPOL)
|
|
sbrc r16, SPIHW_MODE_CPHA_BIT
|
|
sbr r17, (1<<CPHA)
|
|
sbrc r16, SPIHW_MODE_SPEED0_BIT
|
|
sbr r17, (1<<SPR0)
|
|
sbrc r16, SPIHW_MODE_SPEED1_BIT
|
|
sbr r17, (1<<SPR1)
|
|
sbr r17, (1<<SPE) | (1<<MSTR)
|
|
outr SPCR, r17
|
|
|
|
; setup SPSR
|
|
clr r17
|
|
sbrc r16, SPIHW_MODE_DOUBLESPEED_BIT
|
|
sbr r17, (1<<SPI2X)
|
|
outr SPSR, r17
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine SPIHW_MasterStop @global
|
|
;
|
|
; Stop SPI hardware master.
|
|
|
|
; @clobbers r16
|
|
|
|
SPIHW_MasterStop:
|
|
; sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
|
|
inr r16, SPCR
|
|
cbr r16, (1<<SPE)
|
|
outr SPCR, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine spiHwSelectDevice
|
|
;
|
|
; Select given device via SS0-SS2 pins
|
|
;
|
|
; @param r17=device
|
|
; @clobbers none
|
|
|
|
spiHwSelectDevice:
|
|
cbi SPIHW_SS0_OUTPUT, SPIHW_SS0_PIN
|
|
sbrc r17, 0
|
|
sbi SPIHW_SS0_OUTPUT, SPIHW_SS0_PIN
|
|
cbi SPIHW_SS1_OUTPUT, SPIHW_SS1_PIN
|
|
sbrc r17, 1
|
|
sbi SPIHW_SS1_OUTPUT, SPIHW_SS1_PIN
|
|
cbi SPIHW_SS2_OUTPUT, SPIHW_SS2_PIN
|
|
sbrc r17, 2
|
|
sbi SPIHW_SS2_OUTPUT, SPIHW_SS2_PIN
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine SPIHW_MasterTransfer @global
|
|
;
|
|
; Complete transfer sending ony byte and receiving another.
|
|
;
|
|
; @param r16 byte to send
|
|
; @param r16 byte received
|
|
; @clobbers none
|
|
|
|
SPIHW_MasterTransfer:
|
|
rcall SPIHW_MasterSendByte ; (none)
|
|
rjmp SPIHW_WaitForTransferComplete ; (none)
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine SPIHW_MasterSendByte @global
|
|
;
|
|
; Send a byte to the SPI interface. Does not wait for result, you need to
|
|
; call @ref SPIHW_WaitForTransferComplete to complete the request and to
|
|
; get the response.
|
|
; This allows for transfers in background so that the caller can do other stuff
|
|
; instead of idly waiting for the transfer to complete.
|
|
; However, before calling this routine again you MUST call SPIHW_WaitForTransferComplete!
|
|
|
|
; @param r16 byte to send
|
|
; @clobbers none
|
|
|
|
SPIHW_MasterSendByte:
|
|
outr SPDR, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine SPIHW_WaitForTransferComplete @global
|
|
;
|
|
; Wait for a transfer to complete and return the byte received.
|
|
;
|
|
; @return r16 byte received
|
|
; @clobbers none
|
|
|
|
SPIHW_WaitForTransferComplete:
|
|
inr r16, SPSR
|
|
sbrs r16, SPIF
|
|
rjmp SPIHW_WaitForTransferComplete
|
|
inr r16, SPDR
|
|
ret
|
|
; @end
|
|
|
|
|
|
|