📄 lpstreaming.asm
字号:
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 + -