📄 lpspi.asm
字号:
;-----------------------------------------------------------------------------
;
; Filename: lpSpi.asm
;
; Description: SPI based LP Radio access functions
;
; PSoC or EnCoRe2/PRoC SPI is supported via an external EQU
;
; 3 or 4 wire SPI is supported via an external EQU
;
; Multiplexed MOSI/IRQ is supported via an external EQU
;
;-----------------------------------------------------------------------------
; WirelessUSB LP Radio Driver Version 1.1
;-----------------------------------------------------------------------------
;
; Copyright 2005-2006, Cypress Semiconductor Corporation.
;
; This software is owned by Cypress Semiconductor Corporation (Cypress)
; and is protected by and subject to worldwide patent protection (United
; States and foreign), United States copyright laws and international
; treaty provisions. Cypress hereby grants to licensee a personal,
; non-exclusive, non-transferable license to copy, use, modify, create
; derivative works of, and compile the Cypress Source Code and derivative
; works for the sole purpose of creating custom software in support of
; licensee product to be used only in conjunction with a Cypress integrated
; circuit as specified in the applicable agreement. Any reproduction,
; modification, translation, compilation, or representation of this
; software except as specified above is prohibited without the express
; written permission of Cypress.
;
; Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
; WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
; Cypress reserves the right to make changes without further notice to the
; materials described herein. Cypress does not assume any liability arising
; out of the application or use of any product or circuit described herein.
; Cypress does not authorize its products for use as critical components in
; life-support systems where a malfunction or failure may reasonably be
; expected to result in significant injury to the user. The inclusion of
; Cypress' product in a life-support systems application implies that the
; manufacturer assumes all risk of such use and in doing so indemnifies
; Cypress against all charges.
;
; Use may be limited by and subject to the applicable Cypress software
; license agreement.
;
;-----------------------------------------------------------------------------
;--------------------------------------------------------------------------;
; ;
; I N C L U D E F I L E S ;
; ;
;--------------------------------------------------------------------------;
INCLUDE "lpradio.inc"
INCLUDE "spim_radio.inc"
INCLUDE "psocgpioint.inc"
INCLUDE "lpregs.inc"
INCLUDE "lpIrqMacros.inc"
INCLUDE "memory.inc"
;-----------------------------------------------------------------------------
IF (LP_SPI) ; Just shorter names for SPI I/O for local scope
SPI_CTRL_REG: EQU SPIM_Radio_CONTROL_REG
SPI_TX_REG: EQU SPIM_Radio_TX_BUFFER_REG
SPI_RX_REG: EQU SPIM_Radio_RX_BUFFER_REG
SPI_TX_EMPTY: EQU SPIM_Radio_SPIM_TX_BUFFER_EMPTY
SPI_DONE: EQU SPIM_Radio_SPIM_SPI_COMPLETE
SPI_RX_FULL: EQU SPIM_Radio_SPIM_RX_BUFFER_FULL
ELSE ; not LP_SPI
SPI_RX_REG: EQU SPIDATA ; PRoC/enCoRe II use same reg
SPI_TX_REG: EQU SPIDATA ; PRoC/enCoRe II use same reg
ENDIF
;--------------------------------------------------------------------------;
; ;
; V A R I A B L E S ;
; ;
;--------------------------------------------------------------------------;
AREA InterruptRAM(ram) ; Variables on RAM Page 0
IF (SYSTEM_LARGE_MEMORY_MODEL)
; Although contrary to the big-endian ImageCraft compiler,
; Little-endian makes clearner LMM/SMM macros.
RadioWipPtr:: BLK 2 ; Working pointer (LSB, MSB, little-endian)
RadioWipLen:: BLK 1 ; Working buffer length.
RadioPtr:: BLK 2 ; SPI access routine parameter (little-endian)
RadioLen:: BLK 1 ; SPI access routines parameter - length.
ELSE
RadioWipPtr:: BLK 1 ; Working pointer.
RadioWipLen:: BLK 1 ; Working buffer length.
RadioPtr:: BLK 1 ; Parameter to SPI access routines - address.
RadioLen:: BLK 1 ; Parameter to SPI access routines - length.
ENDIF
RadioSpiTemp: BLK 1 ; Local working temp.
;--------------------------------------------------------------------------;
; ;
; M A C R O D E F I N I T I O N S ;
; ;
;--------------------------------------------------------------------------;
macro RADIO_SELECT
and reg[LP_nSS_Data_ADDR],~LP_nSS_MASK ; Assert Slave Select
IF MUXED_IRQ
or reg[P15CR], (SPI_USE | OUTPUT_EN) ; P1.5 is SPI MOSI out
ENDIF
endm
macro RADIO_DESELECT
IF MUXED_IRQ
and reg[P15CR], ~(SPI_USE | OUTPUT_EN) ; P1.5 is LP IRQ input
ENDIF
or reg[LP_nSS_Data_ADDR], LP_nSS_MASK ; Release Slave Select
endm
;-----------------------------------------------------------------------------
macro E2_CLR_SPI_RXTX_FLAGS
IF (LP_SPI) ; PSoC SPI does nothing
ELSE ; PRoC/enCoRe II ------------------------------------------------------
mov reg[INT_CLR0],~(INT_MSK0_SPI_TX | INT_MSK0_SPI_RX)
ENDIF
endm
;-----------------------------------------------------------------------------
SPI_USE: equ 0x80
OUTPUT_EN: equ 0x01
SPI_SWAP: equ 0x80
;-----------------------------------------------------------------------------
macro SET_SPI_IN
IF THREE_WIRE_SPI
or reg[SPICR], SPI_SWAP ; Make the I/O pin an input
ENDIF ;THREE_WIRE_SPI
endm
;-----------------------------------------------------------------------------
macro SET_SPI_OUT
IF THREE_WIRE_SPI
and reg[SPICR], ~SPI_SWAP ; Make the I/O pin an output
ENDIF ;THREE_WIRE_SPI
endm
;-----------------------------------------------------------------------------
macro SPI_TX_EMPTY_WAIT
IF (LP_SPI) ; ---------------------------------------------------------
.L2: TST REG[SPI_CTRL_REG], SPI_TX_EMPTY ; (TST opcode preserves CRY)
ELSE ; PRoC/enCoRe II ------------------------------------------------------
.L2: TST REG[INT_CLR0], INT_MSK0_SPI_TX ; (TST opcode preserves CRY)
ENDIF ; ----------------------------------------------------
JZ .L2
endm
macro SPI_RX_EMPTY_WAIT
IF (LP_SPI) ; ---------------------------------------------------------
.L2: TST REG[SPI_CTRL_REG], SPI_TX_EMPTY ; (TST opcode preserves CRY)
ELSE ; PRoC/enCoRe II ------------------------------------------------------
.L2: TST REG[INT_CLR0], INT_MSK0_SPI_RX ; (TST opcode preserves CRY)
ENDIF ; ----------------------------------------------------
JZ .L2
endm
;-----------------------------------------------------------------------------
;--------------------------------------------------------------------------;
; ;
; C O D E ;
; ;
;--------------------------------------------------------------------------;
AREA UserModules (ROM, REL)
DISABLE_CODE_COMPRESSION
;-----------------------------------------------------------------------------
;
; Some comments on the operation of the SPI PSoC block:
;
; The SPI_DONE and SPI_TX_EMPTY status
; bits are self-clearing. After you've read SPI_CTRL_REG these
; bits will be cleared. During a multibyte SPI transaction we use the
; SPI_TX_EMPTY status to pace the data, but at the end
; of a transaction we use SPI_DONE to determine that
; we can de-assert the slave select.
;
; Although the hardware generates the SPI_CTRL_REG status
; one full byte time before SPI_TX_EMPTY if you are
; not reading the SPI_CTRL_REG register fast enough you might
; see both of those status indications occur together, and after you've
; read the SPI_CTRL_REG status it will clear and you will not see
; it again. In the case that the SPI clock is very fast, or if interrupts
; are left enabled during the execution of these routines then it is very
; possible to see both of these indications occur together.
;
; In order for these routines to allow interrupts to be enabled during their
; execution they are structured to allow the assertion of the two status
; bits SPI_DONE and SPI_TX_EMPTY
; on the same read of SPI_CTRL_REG. Although this is a real world
; condition, you will only see it under stressed conditions.
;
; One other strangeness of the PSoC SPI block is that the
; SPI_DONE status ONLY INDICATES THE STATE OF THE
; SHIFTER - it does not include the state of the holding register. This
; means that when we need to poll SPI_DONE at the
; end of a transaction we need to make sure we see the status incdication
; SPI_TX_EMPTY to know that the complete wasn't for
; the previous byte.
;
;-----------------------------------------------------------------------------
;--------------------------------------------------------------------------;
; ;
; I N I T I A L I Z A T I O N ;
; ;
;--------------------------------------------------------------------------;
.section
;-----------------------------------------------------------------------------
;
; RadioReset: Send Soft Reset command to radio.
;
; 'C' Call: void RadioReset(void);
;
; Assembly Call: A: none
; X: none
;
; Assembly Return: A: lost
; X: lost
; CUR_PP: Large Memory Model sets to RadioDriverRamPage
;-----------------------------------------------------------------------------
_RadioReset::
RadioReset::
RAM_SETPAGE_CUR >RadioDriverRamPage
RADIO_DESELECT
MOV [RadioLen], 255 ; Start out assuming a big buffer.
MOV A, MODE_OVERRIDE_ADR ; Reset Radio through SPI (soft reset)
MOV X, RST ; (don't use LP RST pin)
IF (MUXED_IRQ & THREE_WIRE_SPI)
CALL RadioWrite ; Issue soft-reset
MOV A, IO_CFG_ADR ;
MOV X, SPI_3_PIN | IRQ_GPIO ; Enable IRQ/MOSI mux + 3-wire SPI
ELSE
IF MUXED_IRQ; and non-3-wire SPI
CALL RadioWrite ; Issue soft-reset
MOV A, IO_CFG_ADR ;
MOV X, IRQ_GPIO ; Only enable IRQ muxed on MOSI pin
ENDIF
IF THREE_WIRE_SPI; and non-Muxed IRQ
CALL RadioWrite ; Issue soft-reset
MOV A, IO_CFG_ADR ;
MOV X, SPI_3_PIN ; Only enable 3-wire SPI
ENDIF
ENDIF
JMP RadioWrite
.endsection
.section
;-----------------------------------------------------------------------------
;
; RadioWriteSwapped: Write a single byte to Radio register.
; Same as RadioWrite(), except A and X are swapped because
; C calling convention makes it easier to set registers.
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -