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

📄 lpstreaming.asm

📁 the newest cypress wirelessusb LP and PROC LP radio driver
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        OR      A, FRC_END_STATE        ; Force to User's desired end-state
        MOV     X, XACT_CFG_ADR         ;
        CALL    RadioWriteSwapped       ;
.wait:  MOV     A, XACT_CFG_ADR         ; Wait for FRC_END_STATE bit in
        CALL    RadioRead               ;  XACT_CFG register to clear
        AND     A, FRC_END_STATE        ;  indicating the Force End is
        JNZ     .wait                   ;  complete.
        ; ------------------------------

isAwake:
        MOV     A, CLK_OVERRIDE_ADR     ;
        MOV     X, 0                    ; Stop forcing the RXF clock
        CALL    RadioWrite              ;

        MOV     A, [RadioTemp3]         ; Byte count
        JMP     RadioEndTransmit        ; Set radio mode IDLE
.endsection


.section
;-----------------------------------------------------------------------------
;
; RadioForceState:  Force radio to desired state NOW.
;                   Updates global RadioXacConfig shadow variable.
;                   Sometimes used to wake/sleep radio to measure voltage.
;
;  We must ensure SLEEP only transitions to IDLE (and recovers if problem).
;  RadioForceState(END_STATE_IDLE) MUST be called prior to TX_GO or RX_GO 
;   whenever radio may be in SLEEP.
;
; 'C' Call:        void RadioForceState(XACT_CONFIG endStateBitsOnly);
;
; Assembly Call:   A: RadioXactConfig END_STATE bits only, no ACK_EN, ACK_TO
;                  X: Undefined
;
; Assembly Return: A,X: Undefined
;-----------------------------------------------------------------------------
_RadioForceState::
 RadioForceState::
        RAM_SETPAGE_CUR >RadioDriverRamPage

        ; Only invoke when radio is in SLEEP
        PUSH    A                       ; Save target state
        IsRadioSleep
        JNZ     .noCdt                  ; Current state IS NOT SLEEP
        MOV     A, END_STATE_IDLE       ; Get Radio IDLE before anything else
        CALL    forceState              ; Force SLEEP--->IDLE
.noCdt:
        POP     A                       ; Restore target state
        ; fallthru                      ; NON_SLEEP ---> User's Radio state

forceState:     
        CALL    frcState                ; Write State w/Force
        MOV     [RadioScratch0], 0      ; Delay 5 mS max timeout
wait5:  MOV     A, XACT_CFG_ADR         ;
        CALL    RadioRead               ;
        AND     A, FRC_END_STATE        ;
        JZ     return                   ; Wait for Force End State completion
        DEC     [RadioScratch0]
        JNZ     wait5                   ; No timeout yet
                ; timeout possible ONLY when going SLEEP to IDLE
        MOV     A, END_STATE_SLEEP
        CALL    frcState
        MOV     A, END_STATE_IDLE       ; Get Radio IDLE before anything else
        JMP     forceState

frcState:       
        AND     [RadioXactConfig],  ~END_STATE_MSK
        OR      A, [RadioXactConfig]    ; Merge w/existing ACK_EN, ACK_TO bits
        OR      A, FRC_END_STATE        ; Force the State
        JMP     RadioSetXactConfig

; ----------------------------------------------------------------------------
; wakeupRadio - If radio is in SLEEP, wake it up.  
;               Leave "unforced" END STATE in (RadioXactConfig) unchanged.
; ----------------------------------------------------------------------------
wakeupRadio:
        IsRadioSleep
        JNZ     return                  ; Radio already awake
        MOV     A, END_STATE_IDLE
        CALL    forceState              ; Radio SLEEP ---> IDLE

        MOV     A, [RadioXactConfig]    ; Restore unforced END state to SLEEP
        AND     A, ~END_STATE_MSK
       ;OR      A, END_STATE_SLEEP      ; redundant since END_STATE_SLEEP == 0
        JMP     RadioSetXactConfig      ; Write without FORCE bit

return: RET
.endsection

.section
;-----------------------------------------------------------------------------
;
; RadioGetRssi:    Returns the receiver signal strength indicator.
;
; 'C' Call:        RADIO_RSSI RadioGetRssi(void);
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: Rssi
;                  X: Undefined
;-----------------------------------------------------------------------------
_RadioGetRssi::
 RadioGetRssi::
        MOV     A, RSSI_ADR
        JMP     RadioRead
.endsection

.section
;-----------------------------------------------------------------------------
;
; RadioAbort:      Abort a receive operation.
;
; 'C' Call:        RADIO_LENGTH RadioAbort(void);
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: RADIO_ABORT_SUCCESS or Length of valid Rx packet
;                  X: Undefined
;-----------------------------------------------------------------------------
_RadioAbort::
 RadioAbort::
        RAM_SETPAGE_CUR >RadioDriverRamPage
        TST     [RadioState], RADIO_RX  ; This Abort handling is RX specific.
        JZ      .Abort

        ;  Don't issue Force End if receive has started.
        MOV     X, ABORT_EN             ; Try to avoid committing to a Receive
        MOV     A, RX_ABORT_ADR         ;  packet by invoking Digital Loopback
        CALL    RadioWrite              ;
        ; ------------------------------
        MOV     X, 64                   ; Delay to see if SOP arrives
.L1:    DEC     X       ; 4 cycles      ;
        JNZ     .L1     ; 5 cycles      ; (9 * 64) / 12 MHz = 48 uS
        ; ------------------------------
        MOV     A, RX_IRQ_STATUS_ADR    ; See if Rx packet has started
        CALL    RadioReadStatusDebounced;
        OR      [RadioState], A         ; Make bits sticky
        TST     [RadioState], SOFDET_IRQ
        JNZ     .RxOk                   ; Rx packet has started, finish it
        CALL    RadioRxCleanup          ; Rx packet blocked, issue FORCE_END

.Abort: MOV     A, RADIO_ABORT_SUCCESS
        JMP     .AbortExit

; ----------------------------------------------------------------------------
; Receiving a packet, allow to finish naturally.
; Probably has errors (RXE) because we activated Digital Loopback,
;  but if Loopback activated during AutoAck, we'll have a valid packet
;  (which was AutoAcked, so we'd better not discard it!).
; ----------------------------------------------------------------------------
.RxOk:  CALL    RadioGetReceiveState    ; Keep servicing receiver
        AND     A, RXE_IRQ | RXC_IRQ
        JZ      .RxOk
        CALL    RadioEndReceive         ; A = Rx result
        TST     [RadioState], RXE_IRQ
        JZ      .AbortExit              ; Rx good packet, A = packet length
        MOV     A, RADIO_ABORT_SUCCESS  ; Rx with error(s)

.AbortExit:
        PUSH    A
        MOV     X, 0
        MOV     A, RX_ABORT_ADR         ; Remove digital Loopback
        CALL    RadioWrite
        POP     A
        RET
.endsection

.section
;-----------------------------------------------------------------------------
;
; RadioPoll:       Same as RadioInterrupt() but pushes the Flag register on 
;                  the stack to setup for RETI.
;                  RadioPoll() can be called from a polling loop or an ISR
;                  that can not JMP - ie. an ISR written in 'C'.
;
;                  Unlike RadioInterrupt(), RadioPoll() may destroy registers.
;
; RadioInterrupt:  Manage the radio in an ISR or polling loop.
;
;                  For interrupt systems RadioInterrupt can be called from the
;                  GPIO interrupt. This function does nothing if the IRQ is
;                  not asserted thereby making it easy to share the IRQ with
;                  other GPIO interrupts.
;
;                  Using this function in an IRQ can eliminate latency caused
;                  by calling RadioGetTransmitState and/or 
;                  RadioGetReceveiveState in a polling loop. The state of the 
;                  radio is communicated to outside code through the global 
;                  variable RadioState.
;
;                  RadioInterrupt terminates with a RETI. It is intended to be
;                  the target of a JMP instruction from the interrupt vector
;                  directly in systems where the radio does not share the GPIO
;                  interrupt, or it can be JMP'd to at the end of a ISR that
;                  manages the other GPIO interrupt sources in a system.
;
;                  Because RadioInterrupt is intended to be JMP'd to from the
;                  interrupt vector it leaves the registers unaffected.
;
; 'C' Call:        void RadioInterrupt(void);
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: Untouched
;                  X: Untouched
;-----------------------------------------------------------------------------
_RadioPoll::
 RadioPoll::
        RAM_SETPAGE_CUR >RadioDriverRamPage
        PUSH_F_VIA_RAM                  ; PUSH F and disable GIE

; ----------------------------------------------------------------------------
; RadioInterrupt() - Jumped-to via an ISR (or simulated ISR)
;
; Assumes:      1. GIE is disabled
;               2. F register on top of stack (arrived via JMP from an ISR)
;               3. Direct Memory instructions access Page 0
;
; Large Memory Model: must preserve CUR_PP and possibly MVR_PP.
;                     may leave STK_PP = SYSTEM_STACK_PAGE on exit.
; ----------------------------------------------------------------------------
_RadioInterrupt::
 RadioInterrupt::
        TST_IRQ_PIN
        JZ      .exit0                  ; IRQ not asserted, just RETI

        PUSH    A                       ; Save Regs
        PUSH    X                       ;
        ISR_REG_PRESERVE (CUR_PP)       ; LMM saves CUR_PP reg

        TST     [RadioState], RADIO_TX
        JZ      .rxChk
.txChk:
        ISR_REG_PRESERVE (MVR_PP)       ; LMM saves MVR_PP
        CALL    RadioGetTransmitStateIsr  
        ISR_REG_RESTORE  (MVR_PP)       ; LMM restores MVR_PP
        JMP     .exit1                   

.rxChk: TST     [RadioState], RADIO_RX
        JZ      .exit1
        CALL    RadioGetReceiveStateIsr
        ; LMM Note:
        ;  RadioGetReceiveStateIsr() leaves STK_PP set to SYSTEM_STACK_PAGE.
        ;  Only a VERY unusual application would have a problem with this.
.exit1:
        ISR_REG_RESTORE (CUR_PP)        ; LMM restores CUR_PP
        POP     X                       ; Restore Regs
        POP     A                       ;
.exit0:
        POP_F_RET                       ; Same as RETI
.endsection


.section
;-----------------------------------------------------------------------------
;
; RadioGetReceiveStatus:
;                  Returns the receiver status register.
;
; 'C' Call:        RADIO_RX_STATUS RadioGetReceiveStatus(void);
;
; Assembly Call:   A: Unused
;                  X: Unused
;
; Assembly Return: A: Status
;                  X: Undefined
;-----------------------------------------------------------------------------
_RadioGetReceiveStatus::
 RadioGetReceiveStatus::
        MOV     A, RX_STATUS_ADR
        JMP     RadioRead
.endsection

        ENABLE_CODE_COMPRESSION
; ############################################################################
; END OF lpStreaming.asm
; ############################################################################

⌨️ 快捷键说明

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