⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpspi.asm

📁 Cypress公司开发的2.4G无线键盘鼠标及其Bridge源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        E2_CLR_SPI_RXTX_FLAGS           
        MOV     REG[SPI_TX_REG], A      ; Write the address

  IF (LP_SPI)   ; ---------------------------------------------------------
    IF (SYSTEM_LARGE_MEMORY_MODEL)
        MOV     A, [RadioWipPtr+1]      ; MSByte adr 
        RAM_SETPAGE_MVR A               ; MVR operates on RadioWipPtr page
    ENDIF       
.Burst: MVI     A, [RadioWipPtr+0]      ; Get the data
        SPI_TX_EMPTY_WAIT
        MOV     REG[SPI_TX_REG], A
        DEC     X
        JNC     .Burst

        ; All done bursting, wait for last byte to leave the holding register
        SPI_TX_EMPTY_WAIT
                    
        ; Wait for shifting to complete and the SPI transaction to finish.
.L1:    TST     REG[SPI_CTRL_REG],SPI_DONE
        JZ      .L1

  ELSE ; PRoC/enCoRe II ------------------------------------------------------

    IF (SYSTEM_LARGE_MEMORY_MODEL)
        MOV     A, [RadioWipPtr+1]      ; MSByte adr 
        RAM_SETPAGE_MVR A               ; MVR operates on RadioWipPtr page
    ENDIF       
.Burst: 
        MVI     A, [RadioWipPtr+0]      ; Get the data.
        SPI_TX_EMPTY_WAIT
        E2_CLR_SPI_RXTX_FLAGS
        MOV     REG[SPI_TX_REG], A      ; Write the address
        DEC     X
        JNC     .Burst

        ; All done bursting, wait for last byte to leave the holding register
        SPI_TX_EMPTY_WAIT

        ; Clear RX flag, for next Loop, it takes 9+4+9=22 cycles to finish
        MOV     REG[INT_CLR0], ~INT_MSK0_SPI_RX 
                    
        ; Wait for shifting to complete and the SPI transaction to finish.
.L1:    TST     REG[INT_CLR0],INT_MSK0_SPI_RX
        JZ      .L1
        E2_CLR_SPI_RXTX_FLAGS
  ENDIF ; LP_SPI        ; ----------------------------------------------------
        RADIO_DESELECT
.Done:
        POP_F_RET

.endsection

.section
;-----------------------------------------------------------------------------
;
; RadioBurstReadWip:
;                  Read a sequence of bytes from a sequence of Radio registers
;                  using RadioWipPtr as the buffer pointer.
;
; Assembly Call:   RadioWipPtr: Address of buffer to read.
;                  A: The register number to write.
;                     (Top two bits MUST be clear.)
;                  X: Length of the buffer.
;
; Assembly Return: A: Undefined
;                  X: Undefined
;-----------------------------------------------------------------------------
 RadioBurstReadWip::
        OR      A, bSPI_AUTO_INC        ; Set the increment flag.
        JMP     RadioFileReadWip

.endsection

.section
;-----------------------------------------------------------------------------
;
; RadioBurstRead:  Read a sequence of bytes from a sequence of Radio registers
;
; 'C' Call:        void RadioBurstRead(unsigned char cnt);
;                  Must set RadioPtr via RadioSetPtr() before RadioBurstRead.
;                  
; See RadioFileRead() for entry/exit parameters
;-----------------------------------------------------------------------------
 RadioBurstRead::
_RadioBurstRead::
        OR      A,bSPI_AUTO_INC         ; Set the increment flag.

;-----------------------------------------------------------------------------
;
; RadioFileRead:   Read a sequence of bytes from a single Radio registers.
;
;                      time->           |8spiclk|8spiclk|8spiclk|
;                  Assert Slave Select  |       |       |       |
;                  Write Address        |       |       |       |
;                  Wait for Empty(1)----+       |       |       |
;                  Write Nul Data               |       |       |
;                  Wait for Empty(2)------------+       |       |
;                  Write Nul Data                       |       |
;                  Read Nul Data                        |       |
;                  Wait for Empty(3)--------------------+       |
;                  Write Nul Data                               |
;                  Read Data                                    |
;                  Wait for Empty and complete------------------+
;                  Read Data
;                  De-assert Slave Select
;
;                  The main loop of this routine is a littler slower than it 
;                  should be. With a 12MHz CPU the burst is not always 
;                  continuous. There are occasional gaps between bytes in the
;                  burst. It should be possible to correct this, but it's a
;                  minor problem and this is already pretty convoluted to deal
;                  with the latency caused by the TX and RX holding buffers.
;
;                  Properly handles all length cases, including zero and one. 
;
; 'C' Call:        (Must set RadioPtr and RadioLen by calling RadioSetPtr 
;                  prior to RadioFileRead.)
;                  void RadioFileRead(BYTE regAddr, BYTE cnt);
;
; Assembly Call:   A: The register number to write, top 2 bits MUST be clear!
;                  X: Length of the buffer.
;           RadioPtr: Address of buffer to read.
;           RadioLen: Size of buffer
;
; Assembly Return: A: Undefined
;                  X: Undefined
;             CUR_PP: Large Memory Model sets to RadioDriverRamPage
;             STK_PP: Large Memory Model sets to SYSTEM_STACK_PAGE
;-----------------------------------------------------------------------------
 RadioFileRead::
_RadioFileRead::
        RAM_SETPAGE_CUR >RadioDriverRamPage
  IF (SYSTEM_LARGE_MEMORY_MODEL)
        MOV     [RadioWipPtr+1], [RadioPtr+1] ; LMM: MSB working pointer
  ENDIF
        MOV     [RadioWipPtr+0], [RadioPtr+0] ; Initialize working pointer
        MOV     [RadioWipLen], [RadioLen]     ;  and length.

RadioFileReadWip::
        RAM_SETPAGE_CUR >RadioDriverRamPage
        PUSH_F_VIA_RAM                  ; PUSH F and disable GIE
        DEC     X                       ; Check for zero length case.
        JC      .exit0                  ; If zero, nothing to do.

        ; Here, X = number of bytes in the file read -1. The final byte is
        ;  handled specially by waiting for COMPLETE instead of EMPTY at
        ;  .LastByte below.
        ; --------------------------------------------------------------------
        RADIO_SELECT
        E2_CLR_SPI_RXTX_FLAGS
        MOV     REG[SPI_TX_REG], A      ; Write SPI address.

        ; --------------------------------------------------------------------
        ; Using the SP as a write data pointer is 6-cycles faster than MVI.
        ;       (Since GIE is already disabled, using SP is safe).
        ; --------------------------------------------------------------------
        SWAP    A, SP
        SWAP    [RadioWipPtr+0], A      ; LSByte of pointer
        SWAP    A, SP                   ; SP = RadioWipPtr
  IF (SYSTEM_LARGE_MEMORY_MODEL)
        MOV     A, [RadioWipPtr+1]      ; MSByte of pointer (page #)
        MOV     REG[STK_PP], A
  ENDIF

        SPI_RX_EMPTY_WAIT                   
        SET_SPI_IN                   
        E2_CLR_SPI_RXTX_FLAGS
        MOV     REG[SPI_TX_REG], A      ; Write null data.
;
; We need to get three items set up for this execution of the routine and the
; next as well based on whether there is room in the buffer.
;                bytes to read(X) - space in buffer(RadioWipLen)
;                C (RadioWipLen>X)  NC (RadioWipLen<=X)
;-----------------------------------------------------------------------------
; Reads that fit in buffer : X             = X                = RadioWipLen
; Reads thrown away        : RadioSpiTemp  = 0                = X-RadioWipLen
; Bytes left in buffer     : RadioWipLen   = RadioWipLen-X    = 0
;                                                         
        MOV     A, X
        SUB     A, [RadioWipLen]        ; CRY = 1 if user's buffer TOO SMALL
        SPI_TX_EMPTY_WAIT               ; cry preserved
        JNC     .S1                     ; User buf   holds ALL   Radio Rx data

        MOV     [RadioSpiTemp], 0       ; User buf too small for Radio Rx data
        MOV     A, X
        SUB     [RadioWipLen], A
        JMP     .BurstBottom

        ; A = number of bytes we are going to move -1.
        ; We need to subtract the total number of bytes which is A+1.
        ;
.S1:    MOV     [RadioSpiTemp], A
        MOV     X, [RadioWipLen]
        MOV     [RadioWipLen], 0
        JMP     .BurstBottom

.BurstLoop1:
        E2_CLR_SPI_RXTX_FLAGS
        MOV     REG[SPI_TX_REG], A      ; Write null data.
        SPI_TX_EMPTY_WAIT
        MOV     A, REG[SPI_RX_REG]      ; Get SPI Rx data
        PUSH    A                       ; Save data in buffer, not real stack
                        
.BurstBottom:
        DEC     X                       ; Count
        JNC     .BurstLoop1             ; Keep copying to User Buffer

        ; User Buffer is FULL, if Radio still has Rx data then read it and 
        ; discard.  If more data to dump, count is in RadioSpiTemp.
        MOV     X, [RadioSpiTemp]
        JMP     .trash0

.trash: E2_CLR_SPI_RXTX_FLAGS
        MOV     REG[SPI_TX_REG], A        
        SPI_TX_EMPTY_WAIT               ; Don't bother reading SPI Rx data
.trash0:                                ; because User's Buffer is FULL
        DEC     X
        JNC     .trash              

        ; --------------------------------------------------------------------
        ; Moved all data except for one last byte. Wait for it and if 
        ;  we have room in the buffer, get it and store it.
        ; --------------------------------------------------------------------
.LastByte:
  IF (LP_SPI)   ; ---------------------------------------------------------
        TST     REG[SPI_CTRL_REG], SPI_DONE
  ELSE ; PRoC/enCoRe II ------------------------------------------------------
        TST     REG[INT_CLR0], INT_MSK0_SPI_RX 
  ENDIF                 ; ----------------------------------------------------
        JZ      .LastByte
        CMP     [RadioWipLen], 0
        JZ      .exit1                  ; Exit w/cleanup
                   
        MOV     A, REG[SPI_RX_REG]      ; Get SPI Rx data 
        PUSH    A                       ; Save data in buffer, not real stack
        DEC     [RadioWipLen]
                        
.exit1:
        E2_CLR_SPI_RXTX_FLAGS
        SET_SPI_OUT
        RADIO_DESELECT
        SWAP    A, SP                   ; Restore SP to STACK
        SWAP    [RadioWipPtr], A        ; Restore SP to STACK
        SWAP    A, SP                   ; Restore SP to STACK
  IF (SYSTEM_LARGE_MEMORY_MODEL)
        MOV     REG[STK_PP], SYSTEM_STACK_PAGE
  ENDIF
                   
.exit0:
        POP_F_RET                       ; Restore GIE bit
.endsection

        ENABLE_CODE_COMPRESSION

; ############################################################################
; END OF lpSpi.asm
; ############################################################################

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -