📄 lpspi.asm
字号:
; Assembly Call: A: Value to write to selected register.
; X: Register number to write, high 2 bits MUST be ZERO !
; -------------------
;
; RadioWrite: Write a single byte to an Radio register.
;
; 'C' Call: void RadioWrite(RADIO_REG_ADDR regAddr, BYTE value);
;
; Assembly Call: A: Register number to write, high 2 bits MUST be ZERO !
; X: Value to write to the selected register.
;
; Assembly Return: A: lost
; X: lost
; CUR_PP: Large Memory Model sets to RadioDriverRamPage
;-----------------------------------------------------------------------------
RadioWriteSwapped::
SWAP A, X
RadioWrite::
_RadioWrite::
OR A, bSPI_WRITE ; Set the Write Bit.
IF THREE_WIRE_SPI ; ------------------------------------------------------
; Note: 3-wire SPI Write can't fallthru to use Read routine
RAM_SETPAGE_CUR >RadioDriverRamPage
PUSH_F_VIA_RAM
RADIO_SELECT
E2_CLR_SPI_RXTX_FLAGS ; Clear TX and RX flag
MOV REG[SPI_TX_REG], A ; Write SPI adr
.L1: TST REG[INT_CLR0],INT_MSK0_SPI_RX ; Address transfer complete?
JZ .L1
E2_CLR_SPI_RXTX_FLAGS ; Clear the TX and RX flag
MOV A,X ; Data from address read is garbage
MOV REG[SPI_TX_REG], A ; Write SPI data
.L2: TST REG[INT_CLR0],INT_MSK0_SPI_RX ; Data transfer complete?
JZ .L2
RADIO_DESELECT
POP_F_RET ; 3-wire SPI returns here
ENDIF ; THREE_WIRE_SPI ; ------------------------------------------------
; 4-wire SPI falls-thru to use RadioRead() to perform the Write
;-----------------------------------------------------------------------------
;
; RadioRead: Read a single byte from an Radio register.
;
; 'C' Call: BYTE RadioRead(RADIO_REG_ADDR regAddr);
;
; Assembly Call: A: The register number to read
; X: READ=unused, fallthru from WRITE=Data
;
; (For both the 'C' and assembly call the top two bits of
; the register number MUST be clear.)
;
; Assembly Return: A: Value from register
; X: lost
; CUR_PP: Large Memory Model sets to RadioDriverRamPage
;-----------------------------------------------------------------------------
RadioRead::
_RadioRead::
RAM_SETPAGE_CUR >RadioDriverRamPage
PUSH_F_VIA_RAM
RADIO_SELECT
E2_CLR_SPI_RXTX_FLAGS
MOV REG[SPI_TX_REG], A ; Write SPI address
SPI_RX_EMPTY_WAIT
SET_SPI_IN ; 3-wire read flips MOSI to MISO
E2_CLR_SPI_RXTX_FLAGS
MOV A, X
MOV REG[SPI_TX_REG], A ; Write SPI data
SPI_RX_EMPTY_WAIT
IF (LP_SPI) ; ------------------------------------------------------------
.L3: TST REG[SPI_CTRL_REG], SPI_DONE
JZ .L3
ENDIF
E2_CLR_SPI_RXTX_FLAGS
MOV A, REG[SPI_RX_REG] ; Get SPI Rx data
SET_SPI_OUT ; 3-wire idles as MOSI
; A = return value
RADIO_DESELECT
POP_F_RET ; Restore F and return
.endsection
.section
;-----------------------------------------------------------------------------
;
; RadioReadRxStatusDebounced:
; Read a single byte from the RX_IRQ_STATUS_ADR register and
; debounce the update of the RXC and RXE bits. If only one of
; those two bits is set, read the register a second time and
; or them together. This second read happens in the same
; SPI transaction as a burst to the same address.
;
; 'C' Call: BYTE RadioReadDebounced(RADIO_REG_ADDR regAddr);
;
; Assembly Call: A: Register # to read
; X: none
;
; Assembly Return: A: Value from register
; X: Untouched
; CUR_PP: Large Memory Model sets to RadioDriverRamPage
;-----------------------------------------------------------------------------
RadioReadStatusDebounced::
_RadioReadStatusDebounced::
RAM_SETPAGE_CUR >RadioDriverRamPage
PUSH_F_VIA_RAM
RADIO_SELECT
E2_CLR_SPI_RXTX_FLAGS
MOV REG[SPI_TX_REG], A ; Write SPI address.
SPI_RX_EMPTY_WAIT
SET_SPI_IN
E2_CLR_SPI_RXTX_FLAGS
MOV REG[SPI_TX_REG], A ; Write SPI data.
SPI_RX_EMPTY_WAIT
IF (LP_SPI) ; ---------------------------------------------------------
.L3: TST REG[SPI_CTRL_REG], SPI_DONE
JZ .L3
ENDIF
; If RXC and RXE (or TXC and TXE) bits match,
; then skip the debounce read
MOV A, REG[SPI_RX_REG] ; Get SPI Rx data
MOV [RadioSpiTemp], A
AND A, RXC_IRQ | RXE_IRQ
JZ .Done ; Both bits are ZERO
CMP A, RXC_IRQ | RXE_IRQ
JZ .Done ; Both bits are ONE
; The Complete and Error bits are different.
; Read again to ensure both bits have updated.
E2_CLR_SPI_RXTX_FLAGS
MOV REG[SPI_TX_REG], A
SPI_RX_EMPTY_WAIT
IF (LP_SPI) ; ---------------------------------------------------------
.L5: TST REG[SPI_CTRL_REG],SPI_DONE
JZ .L5
ENDIF ; ; ---------------------------------------------------------
MOV A, REG[SPI_RX_REG] ; Get SPI Rx data
OR [RadioSpiTemp], A
.Done: MOV A, [RadioSpiTemp] ; Get the return value.
SET_SPI_OUT
RADIO_DESELECT
POP_F_RET
.endsection
.section
;-----------------------------------------------------------------------------
;
; RadioSetPtr: Set the buffer pointer address for RadioBurstRead,
; RadioFileRead, RadioBurstWrite and RadioFileWrite functions
;
; 'C' Call: void RadioSetPtr(unsigned char ramPtr);
;
; Return: CUR_PP: Large Memory Model sets to RadioDriverRamPage
;-----------------------------------------------------------------------------
_RadioSetPtr::
RAM_SETPAGE_CUR >RadioDriverRamPage
MOV [RadioPtr+0], X ; LSByte of pointer
IF (SYSTEM_LARGE_MEMORY_MODEL)
MOV [RadioPtr+1], A ; LMM: MSB 16-bit pointer
ENDIF
RET
.endsection
.section
;-----------------------------------------------------------------------------
;
; RadioSetLength: Set the buffer length for RadioBurstRead & RadioFileRead.
;
; 'C' Call: void RadioSetLength(unsigned char length);
;
; Return: CUR_PP: Large Memory Model sets to RadioDriverRamPage
;-----------------------------------------------------------------------------
_RadioSetLength::
RAM_SETPAGE_CUR >RadioDriverRamPage
MOV [RadioLen], A
RET
.endsection
.section
;-----------------------------------------------------------------------------
;
; RadioBurstWriteWip:
; Write sequence of bytes to sequence of Radio registers.
; Uses RadioWipPtr instead of RadioPtr as the data pointer.
;
; ---------------------
;
; RadioFileWriteWip:
; Write sequence of bytes to singleRadio register.
; Uses RadioWipPtr instead of RadioPtr as the data pointer.
;
; ---------------------
;
; RadioBurstWrite: Write sequence of bytes to sequence of Radio registers.
;
; 'C' Call: void RadioBurstWrite(BYTE regAddr, BYTE cnt);
; Must set RadioPtr via RadioSetPtr() before RadioBurstWrite
;
; ---------------------
;
; RadioFileWrite: Write sequence of bytes to single Radio register.
;
; 'C' Call: void RadioFileWrite(LS_REG_ADDR regAddr, BYTE cnt);
; (Must set RadioPtr via RadioSetPtr() before RadioFileWrite)
; ---------------------
;
; Assembly Call: A: Register number to write, top two bits MUST be clear!
; X: Length of buffer.
; RadioPtr: Address of buffer to write.
;
; Assembly Return: A: Undefined
; X: Undefined
; CUR_PP: Large Memory Model sets to RadioDriverRamPage
; MVR_PP: Large Memory Model sets to RadioWipPtr page
;-----------------------------------------------------------------------------
RadioBurstWriteWip::
OR A, bSPI_AUTO_INC ; Set increment flag
JMP RadioFileWriteWip ; Use existing WIP ptr/ctr
RadioBurstWrite::
_RadioBurstWrite::
OR A, bSPI_AUTO_INC ; Set increment flag.
RadioFileWrite::
_RadioFileWrite::
RAM_SETPAGE_CUR >RadioDriverRamPage
IF (SYSTEM_LARGE_MEMORY_MODEL)
MOV [RadioWipPtr+1], [RadioPtr+1] ; Copy MSByte buffer pointer.
ENDIF
MOV [RadioWipPtr+0], [RadioPtr+0] ; Copy LSByte buffer pointer.
RadioFileWriteWip::
RAM_SETPAGE_CUR >RadioDriverRamPage
PUSH_F_VIA_RAM
DEC X ; If the length is zero
JC .Done ; do nothing at all.
OR A, bSPI_WRITE ; Set the write flag.
RADIO_SELECT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -