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

📄 psocradio.asm

📁 Cypress 的VOIP DEMO 研究VOIP终端的朋友可以研究研究
💻 ASM
📖 第 1 页 / 共 2 页
字号:

.Done:             MOV     A, [RadioSpiTemp]
                                                       ; Get the return value.
		radioDeselect
                                                       ; Deassert the Slave Select
                   RET_RESTORE_IE_THROUGH_X

.endsection
.section
;--------------------------------------------------------------------------------
;
; RadioSetPtr:     Set the buffer pointer address for RadioBurstRead,
;                  RadioFileRead, RadioBurstWrite and RadioFileWrite functions.
;
; 'C' Call:        void RadioSetPtr(unsigned char ramPtr);
;
_RadioSetPtr::     MOV     [RadioPtr], X
                   RET

.endsection
.section
;--------------------------------------------------------------------------------
;
; RadioSetLength:  Set the buffer length for RadioBurstRead & RadioFileRead.
;
; 'C' Call:        void RadioSetLength(unsigned char length);
;
_RadioSetLength::  MOV     [RadioLen], A
                   RET

.endsection
.section
;--------------------------------------------------------------------------------
;
; RadioBurstWriteWip:
;                  Write a sequence of bytes to a sequence of Radio registers.
;                  This, like all the WIP versions of the file read and write
;                  functions uses RadioWipPtr instead of RadioPtr as the data pointer.                   
;
; Assembly Call:   RadioWipPtr: Address of buffer to write.
;                  A: The register number to write.
;                     (Top two bits MUST be clear.)
;                  X: Length of the buffer.
;
; Assembly Return: A: Undefined
;                  X: Undefined
;
 RadioBurstWriteWip::
                   OR      A, bSPI_AUTO_INC            ; Set the increment flag.
                   JMP     RadioFileWriteWip

;--------------------------------------------------------------------------------
;
; RadioBurstWrite: Write a sequence of bytes to a sequence of Radio registers.
;
; 'C' Call:        void RadioBurstWrite(unsigned char regAddr, unsigned char cnt);
;                  (Must set RadioPtr by calling RadioSetPtr prior to RadioBurstWrite.)
;                  
; Assembly Call:   RadioPtr: Address of buffer to write.
;                  A: The register number to write.
;                     (Top two bits MUST be clear.)
;                  X: Length of the buffer.
;
; Assembly Return: A: Undefined
;                  X: Undefined
;
 RadioBurstWrite::
_RadioBurstWrite:: OR      A, bSPI_AUTO_INC            ; Set the increment flag.

;--------------------------------------------------------------------------------
;
; RadioFileWrite:  Write a sequence of bytes to a single Radio register.
;
; 'C' Call:        void RadioFileWrite(LS_REG_ADDR regAddr, BYTE cnt);
;                  (Must set RadioPtr by calling RadioSetPtr prior to RadioFileWrite.)
;
; Assembly Call:   RadioPtr: Address of buffer to write.
;                  A: The register number to write.
;                     (Top two bits MUST be clear.)
;                  X: Length of the buffer.
;
; Assembly Return: A: Undefined
;                  X: Undefined
;
; TODO:            Remove Empty/Complete race and IRQ disable.
;
 RadioFileWrite::
_RadioFileWrite::  MOV     [RadioWipPtr], [RadioPtr]   ; Copy the buffer pointer.
 RadioFileWriteWip::
                   DEC     X                           ; If the length is zero
                   JC      .Done                       ;  do nothing at all.
                   CLEAR_TEMP_IE                       ; Disable global IRQ for this function.
                   OR      A, bSPI_WRITE               ; Set the write flag. 
		radioSelect
                                                       ; Assert Radio Select.
                   MOV     REG[SPIM_Radio_TX_BUFFER_REG],A

.Burst:            MVI     A,[RadioWipPtr]             ; Get the data.
.WaitLoop8:        TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_TX_BUFFER_EMPTY
                   JZ      .WaitLoop8
                   MOV     REG[SPIM_Radio_TX_BUFFER_REG],A
                   DEC     X
                   JNC     .Burst
;
; All done bursting, wait for the last byte to leave the holding register.
;                                                       
.Burst0:           TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_TX_BUFFER_EMPTY
                   JZ      .Burst0
;                    
; Wait for the shifting to complete and the SPI transaction to finish.
;
.WaitComp:         TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_SPI_COMPLETE
                   JZ      .WaitComp
		radioDeselect
                                                       ; Deassert the Slave Select
.Done:             RET_RESTORE_IE_THROUGH_X

.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 by calling RadioSetPtr prior to RadioBurstRead.)
;                  
; Assembly Call:   RadioPtr: 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
;
 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
;
;                  As it stands 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 occasionally gaps between bytes
;                  in the burst. It should be possible to correct this, but it
;                  is a minor problem and this is already pretty convoluted
;                  to deal with the latency caused by the TX and RX holding
;                  buffers.
;
;                  This routine properly handles all cases of length including
;                  zero and one. 
;
; 'C' Call:        (Must set RadioPtr and RadioLen by calling RadioSetPtr prior
;                  to RadioFileRead.)
;                  void RadioFileRead(unsigned char regAddr, unsigned char cnt);
;
; Assembly Call:   RadioPtr: Address of buffer to read.
;                  RadioLen: Size of buffer
;                  A: The register number to write.
;                     (Top two bits MUST be clear.)
;                  X: Length of the buffer.
;
; Assembly Return: A: Undefined
;                  X: Undefined
;
 RadioFileRead::
_RadioFileRead::   MOV     [RadioWipPtr], [RadioPtr]     ; Initialize working pointer
                   MOV     [RadioWipLen], [RadioLen]     ;  and length.
 RadioFileReadWip::DEC     X                             ; Check for zero length case.
                   JC      .Done                         ; If zero, nothing to do.
                   CLEAR_TEMP_IE                         ; Disable global IRQ for this function.
;
; At this point X is the number of bytes in the file read -1. This last one needs
;  to be handled specially by waiting for COMPLETE instead of EMPTY - that is done
;  below at .LastByte.
;

		radioSelect

                   MOV     REG[SPIM_Radio_TX_BUFFER_REG],A ; Write the SPI address.
;
; For speed we are going to use the SP as our data point to write data into the buffer.
;  This would not be possible if interrupts were not disabled. Swap SP<->RadioWipPtr.
;  (PUSH A is 6 cycles faster than MVI).
;
                   SWAP    A, SP
                   SWAP    [RadioWipPtr], A
                   SWAP    A, SP
                   
.WaitLoop1:        TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_TX_BUFFER_EMPTY
                   JZ      .WaitLoop1
                   MOV     REG[SPIM_Radio_TX_BUFFER_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]
;
; This test does not affect C.
;                   
.WaitLoop2:        TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_TX_BUFFER_EMPTY
                   JZ      .WaitLoop2
                                                         ; Throw (address phase) data away .
                   JNC     .1
                   MOV     [RadioSpiTemp], 0
                   MOV     A, X
                   SUB     [RadioWipLen], A
                   JMP     .BurstBottom
;
; A contains the number of bytes we are going to move -1. We need to subtract the total
;  number of bytes which is A+1.
;
.1:                MOV     [RadioSpiTemp], A
                   MOV     X, [RadioWipLen]
                   MOV     [RadioWipLen], 0
                   JMP     .BurstBottom

                        
.BurstLoop1:       MOV     REG[SPIM_Radio_TX_BUFFER_REG],A        
                                                         ; Write null data.
.WaitLoop3:        TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_TX_BUFFER_EMPTY
                   JZ      .WaitLoop3
                   MOV     A,REG[SPIM_Radio_RX_BUFFER_REG]
                                                         ; Get data.
                   PUSH    A                             ;  write the data.
                        
.BurstBottom:      DEC     X                             ; Count
                   JNC     .BurstLoop1                   ; Repeat

;
; We've moved all the data we have room for in the buffer. Do we need to pull any
;  extra data from the register that we are not going to store? If so, the count
;  is in RadioSpiTemp
;                   
                   MOV     X, [RadioSpiTemp]
                   JMP     .BurstBottom2
.BurstLoop2:       MOV     REG[SPIM_Radio_TX_BUFFER_REG],A        
.WaitLoop4:        TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_TX_BUFFER_EMPTY
                   JZ      .WaitLoop4
.BurstBottom2:     DEC     X
                   JNC     .BurstLoop2              
;
; Moved moved all the data except for one last byte. Wait for it and if we have room
;  in the buffer, go get it and store it.
;
.LastByte:         TST     REG[SPIM_Radio_CONTROL_REG],SPIM_Radio_SPIM_SPI_COMPLETE
                   JZ      .LastByte
                   CMP     [RadioWipLen], 0
                   JZ      .Done2
                   
                   MOV     A,REG[SPIM_Radio_RX_BUFFER_REG] ; Get the data 
                   PUSH    A                             ;    and save it.
                   DEC     [RadioWipLen]
                        
.Done2:            radioDeselect

;
; Swap back SP<->RadioWipPtr.
;
                   SWAP    A, SP
                   SWAP    [RadioWipPtr], A
                   SWAP    A, SP
                   
.Done:             RET_RESTORE_IE_THROUGH_X              ; Restore IRQ state.
.endsection

;
; Re-enable code compression.
;
                   ENABLE_CODE_COMPRESSION

⌨️ 快捷键说明

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