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

📄 lpstreaming.asm

📁 the newest cypress wirelessusb LP and PROC LP radio driver
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        TST     [RadioState], TXE_IRQ
        JZ      RGTSDone                ; Tx was error-free, done

        DEC     [RadioRetryCount]       ; Decrement the TX retry count
        JNC     RadioRestartTransmit    ; Retransmit

RGTSDone:
        MOV     A, [RadioState]
        RET

;-----------------------------------------------------------------------------
; We're here, but NOT to move data. 'A' contains the last TX status read with
;  TXC masked out. RadioState has had the last TX status read OR'd in 
;  including TXC bit. If TXC, TXE, and TXBERR are all clear that is an error.
;-----------------------------------------------------------------------------
TxDontMoveData:
        TST     [RadioState], TXC_IRQ
        JNZ     TxCheckTxErrors
        AND     A, (TXE_IRQ | TXBERR_IRQ)
        JNZ     TxIsError
        MOV     A, RX_IRQ_STATUS_ADR    ; Radio saw SOP during AAck Rx window
        CALL    RadioRead               ; (RXE/RXC asserted), clear RXC/RXE
        JMP     TxIsError               ; and treat as Tx Error


;-----------------------------------------------------------------------------
;
; RadioEndTransmit: Completes a transmit operation.
;
; 'C' Call:        void RadioEndTransmit(void);
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: Preserved
;                  X: Undefined
;
_RadioEndTransmit::
 RadioEndTransmit::
        RAM_SETPAGE_CUR >RadioDriverRamPage
        MOV     [RadioState], RADIO_IDLE        ; Clear our status.
        RET
.endsection

.section
;-----------------------------------------------------------------------------
;
; RadioBlockingTransmit:
;                  Transmit a packet. Block execution until it completes.
;                  This function attempts to transmit a packet. The address
;                  of the packet buffer should have previously been set with
;                  a call to RadioSetPtr.
;
;                  This routine gives the user very little control - probably
;                  less than most applications will require. This function is
;                  primarily intended for very simple applications that have
;                  no use for a time-out.
;
; 'C' Call:        RADIO_STATE RadioBlockingTransmit(BYTE retryCt,
;                                                    RADIO_LENGTH len);
;                  (A call to RadioSetPtr must have been made prior to the
;                  call to RadioBlockingTransmit.)
;
; Assembly Call:   A: retryCount
;                  X: length
;                  RadioPtr: Address of packet buffer
;                  
; Assembly Return: A: RADIO_STATE
;                  X: Undefined
;-----------------------------------------------------------------------------
_RadioBlockingTransmit::
 RadioBlockingTransmit::
        CALL    RadioStartTransmit
                   
.Wait:  CALL    RadioGetTransmitState
        MOV     [RadioTemp2], A
        TST     [RadioTemp2], TXC_IRQ | TXE_IRQ
        JZ      .Wait

        JMP     RadioEndTransmit        ; A = RADIO_STATE
.endsection

;--------------------------------------------------------------------------;
;                                                                          ;
;                 R E C E I V E                                            ;
;                                                                          ;
;--------------------------------------------------------------------------;
.section
;-----------------------------------------------------------------------------
;
; RadioStartReceive:
;                  Start the reception of a packet. The location and length of
;                  the packet buffer to receive the data into must have
;                  previously been set with a call to RadioSetPtr and
;                  RadioSetLength.
;
;                  After starting the reception of a packet with this call,
;                  the state of the receive operation should be checked by
;                  calling RadioGetReceiveState. When RadioGetReceiveState
;                  indicates that the transmission has completed a call
;                  should be made to RadioEndReceive.
;
;                  Receive is started by setting RX_GO" bit. All interesting
;                  interrupt enables are set and RadioGetReceiveState
;                  can be called in a polling loop in systems that do not use
;                  interrupts, or can be called directly in an interrupt
;                  handler.
;
;                  After calling RadioStartReceive NO CALLS can be made to the
;                  configuration access routines until receive operation is
;                  terminated with a call to RadioEndReceive or RadioAbort.
;                  Until a call is made to end the receive operation
;                  the only other calls supported are RadioGetReceiveState and
;                  RadioGetRssi.
;
; 'C' Call:        void RadioStartReceive(void);
;                  (A call to RadioSetPtr must have been made prior to the
;                  call to RadioStartReceive.)
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: Undefined
;                  X: Undefined
;-----------------------------------------------------------------------------
_RadioStartReceive::
 RadioStartReceive::
        RAM_SETPAGE_CUR >RadioDriverRamPage
  IF (SYSTEM_LARGE_MEMORY_MODEL)
        MOV     [RadioWipPtr+1], [RadioPtr+1] ; MSByte of pointer
  ENDIF
        MOV     [RadioWipPtr+0], [RadioPtr+0]
        MOV     [RadioWipLen],   [RadioLen]   ; sizeof(RadioPtr)
        MOV     [RadioState], RADIO_RX
        MOV     [RadioBytesRead], 0

; ----------------------------------------------------------------------------
; If Radio's End State (and implied current State) is SLEEP, need:
;       1) Workaround to startup oscillator.
;       2) Workaround to keep awake briefly at end of receive.
; ----------------------------------------------------------------------------
        IsRadioSleep
        JNZ     .awake                  ; Radio already awake

        CALL    wakeupRadio

        ; Radio End State = IDLE so it has time to clean up at RXE/RXC
        MOV     A, [RadioXactConfig]    ; Don't FORCE END, just let go IDLE
        AND     A, ~END_STATE_MSK       ;  when Rx completes.
        OR      A,  END_STATE_IDLE      ; 
        MOV     X, XACT_CFG_ADR         ; Set register to END_STATE_IDLE,
        CALL    RadioWriteSwapped       ;  but retain user's variable

.awake:
        MOV     A, CLK_OVERRIDE_ADR     ;
        MOV     X, RXF                  ; Keep Rx clock running at RXE/RXC
        CALL    RadioWrite              ;

        MOV     A, RX_CTRL_ADR
        MOV     X, (RX_GO | RXB8_IRQ | RXC_IRQ | RXE_IRQ)
        CALL     RadioWrite

        MOV     A, RX_IRQ_STATUS_ADR
        JMP     RadioRead               // Clr SOP detect bit

;-----------------------------------------------------------------------------
;
; RadioGetReceiveState:
;                  Returns the state of the current receive operation.
;                  This call should be made after RadioStartReceive()
;
;                  Although  bits in the state register in the hardware clear
;                  automatically, we make them sticky until RadioEndReceive.
;
; 'C' Call:        RADIO_STATE RadioGetReceiveState(void);
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: State
;                  X: Undefined
;-----------------------------------------------------------------------------
_RadioGetReceiveState::
 RadioGetReceiveState::
        RAM_SETPAGE_CUR >RadioDriverRamPage
        TST_IRQ_PIN
        JZ      exitRx                  ; Nothing interesting, exit

RadioGetReceiveStateIsr:                ; Entry via RadioInterrupt() wrapper
        MOV     A, RX_IRQ_STATUS_ADR
        CALL    RadioReadStatusDebounced
        OR      [RadioState], A         ; Make bits sticky

        ; RXBERR and RXE imply RXC, so any of these 3 flags implies there's 
        ;  no rush to unload RFIFO.
        AND     A, (RXBERR_IRQ | RXE_IRQ | RXC_IRQ | RXB8_IRQ)
        XOR     A, RXB8_IRQ             ; If more than RXB8_IRQ is SET, then
        JNZ     .rxEnded                ;  Rx ended, RadioEndReceive unloads

        MOV     A, RX_BUFFER_ADR        ; Get RFIFO data on-the-fly
        MOV     X, LP_FIFO_HALF
        CALL    RadioFileReadWip
        ADD     [RadioBytesRead], LP_FIFO_HALF

        MOV     A, RX_CTRL_ADR          ;
        MOV     X, RXB8_IRQ             ;
        CALL    RadioWrite              ; Only expose RXB8
        JMP     .RXB8_tst               ;
                   
.RXB8_set:
        MOV     A, RX_BUFFER_ADR        ; Only RXB8 is exposed on IRQ
        MOV     X, LP_FIFO_HALF         ;  so we know least 8 bytes in RFIFO
        CALL    RadioFileReadWip
        ADD     [RadioBytesRead], LP_FIFO_HALF
.RXB8_tst:
        TST_IRQ_PIN
        JNZ     .RXB8_set               ; Only RXB8 is exposed on IRQ

        MOV     A, RX_CTRL_ADR          ; Expose RXE and RXC also
        MOV     X, (RXB8_IRQ | RXC_IRQ | RXE_IRQ)
        CALL    RadioWrite          
        JMP     RadioGetReceiveState

;
; RXC and/or RXE, RXBERR are set, so radio Rx has ended
;
.rxEnded:
        TST     [RadioState], (RXBERR_IRQ | RXE_IRQ) ; If Error,
        JZ      exitRx                               ;  then set RXC/RXE
        OR      [RadioState], (RXC_IRQ | RXE_IRQ)    ;  because radio is done

exitRx:
        MOV     A, [RadioState]         ;  State calls and return them.
        RET                    
    
;-----------------------------------------------------------------------------
;
; RadioEndReceive: Complete a receive operation.
;
; 'C' Call:        RADIO_LENGTH RadioEndReceive(void);
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: # of bytes copied to User's Buf
;                  X: Undefined
;-----------------------------------------------------------------------------
_RadioEndReceive::
 RadioEndReceive::
        MOV     A, RX_CFG_ADR           ; Read current VLD_EN setting
        CALL    RadioRead               ; (RadioRead also sets CUR_PP)
        MOV     [RadioTemp3], A         ;

        MOV     A, RX_COUNT_ADR         ; Total # bytes through RFIFO
        CALL    RadioRead               ; (RadioRead also sets CUR_PP)
        TST     [RadioTemp3], VLD_EN
        JZ      .S2                     ; Normal (VLD_EN == 0)
        ASL     A                       ; 2x, every data byte has a valid byte
.S2:    MOV     [RadioTemp3], A         ; # Bytes in RFIFO

        SUB     A, [RadioBytesRead]     ; Subtract # bytes we've extracted
                                        ;  leaves # bytes sitting in RFIFO
        TST     [RadioState], RXE_IRQ   ;
        JZ      .S1                     ; No error, unload the final byte(s)      
        MOV     A, LP_FIFO_SIZE         ; RXE, purge full RFIFO to recove
.S1:
        MOV     X, RX_BUFFER_ADR
        SWAP    A, X
        CALL    RadioFileReadWip        ; Final RFIFO unload

        ; --------------------------------------------------------------------
        ; If User wanted END_STATE_SLEEP, then undo 
        ;  RadioStartReceive()'s intermediate END_STATE_IDLE override.
        ; --------------------------------------------------------------------
        IsRadioSleep                    ; If user's end state != SLEEP
        JNZ     isAwake                 ;  then no workaround was invoked.

        ; --------------------------------------------------------------------
        ; RadioRxCleanup() - end of RadioAbort() 
        ; --------------------------------------------------------------------
RadioRxCleanup:                         ;
        MOV     A, [RadioXactConfig]    ;

⌨️ 快捷键说明

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