?? lpnonstreaming.asm
字號:
; handler.
;
; After calling RadioStartReceive NO CALLS can be made to the
; configuration access routines until the receive operation is
; terminated with a call to RadioEndReceive or RadioAbort.
; Until one of those calls 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::
MOV [RadioWipPtr], [RadioPtr]
MOV [RadioWipLen], [RadioLen]
MOV [RadioState], RADIO_RX
MOV [RadioBytesRead], 0
MOV A, RX_CTRL_ADR
MOV X, (RX_GO | RXC_IRQ | RXE_IRQ)
CALL RadioWrite
MOV [RadioRssiShadow], 0
MOV A, RSSI_ADR ; Clear the RSSI.
JMP RadioRead
.endsection
.section
;--------------------------------------------------------------------------------
;
; RadioGetReceiveState:
; Returns the state of the current receive operation.
; This call should be made after starting a receive
; operation with the RadioStartReceive function.
;
; Although the bits in the state register in the hardware clear
; automatically, we make them sticky until the RadioEndReceive.
;
; 'C' Call: RADIO_STATE RadioGetReceiveState(void);
;
; Assembly Call: A: Unused
; X: Unused
;
; Assembly Return: A: State
; X: Undefined
;
_RadioGetReceiveState::
RadioGetReceiveState::
TST REG[LP_IRQ_Data_ADDR], LP_IRQ_MASK ; Anything going on?
JZ RGRSDone ; No, nothing to do.
RadioGetReceiveStateIsr:
MOV A, RX_IRQ_STATUS_ADR
CALL RadioReadStatusDebounced
AND A, (RXBERR_IRQ | RXE_IRQ | RXC_IRQ)
OR [RadioState], A ; bits, save them for furure
TST [RadioState], ( RXBERR_IRQ | RXE_IRQ ) ; If overflow, set the
JZ RGRSDone ; completion bit to force
OR [RadioState], ( RXC_IRQ | RXE_IRQ ) ; the end of packet.
RGRSDone: MOV A, [RadioState] ; State calls and return them.
RET
.endsection
.section
;--------------------------------------------------------------------------------
;
; RadioEndReceive: Completes a transmit operation.
;
; 'C' Call: RADIO_LENGTH RadioEndReceive(void);
;
; Assembly Call: A: Unused
; X: Unused
;
; Assembly Return: A: length of packet
; X: Undefined
;
_RadioEndReceive::
RadioEndReceive:: MOV A, RX_COUNT_ADR ; Get the count.
CALL RadioRead
MOV [RadioTemp3], A
TST [RadioState], RXE_IRQ ; If we had a buffer error...
JZ .1
MOV A, 0x10 ; ...burp full FIFO load.
MOV [RadioTemp3], RADIO_ABORT_SUCCESS
.1: MOV X, RX_BUFFER_ADR
SWAP A, X
CALL RadioFileReadWip
RadioRxCleanup: MOV A, [RadioXactConfig] ; Abort by writing the FRC_END_STATE
OR A, FRC_END_STATE ; bit in the XACT_CFG register.
MOV X, XACT_CFG_ADR ; We don't touch the current end state.
CALL RadioWriteSwapped
.abortLoop: MOV A, XACT_CFG_ADR ; Wait for the FRC_END_STATE
CALL RadioRead ; bit in the XACT_CFG register
AND A, FRC_END_STATE ; to cleart indicating the force has
JNZ .abortLoop ; completed.
MOV A, [RadioTemp3] ; Return the count.
JMP RadioDone
.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
CALL RadioRead
OR [RadioRssiShadow], A
RET
.endsection
.section
;--------------------------------------------------------------------------------
;
; RadioAbort: Aborts a transmit or receive operation.
;
; 'C' Call: void RadioAbort(void);
;
; Assembly Call: A: Unused
; X: Unused
;
; Assembly Return: A: Undefined
; X: Undefined
;
_RadioAbort::
RadioAbort:: TST [RadioState], RADIO_RX ; This Abort handling is RX specific.
JZ .Done
;
; From here to .Abort is CDT3940 work-around. (Work-around ticket is CDT4056.) Force End State
; should not be used to abort a receive if a SOP has already happened.
;
MOV X, ABORT_EN ; Disrupt any pending receive by
MOV A, RX_ABORT_ADR ; enabling abort
CALL RadioWrite
MOV X, 40 ; After we've used the dig-loop to
.1: ; disable the receiver we need to
; give the pipe a while to settle
; Read the RSSI register a few times
DEC X ; to update the SOP.
JNZ .1
CALL RadioGetRssi
TST [RadioRssiShadow], 0x80 ; Has the RSSI SOP bit been set?
JNZ .2 ; No SOP yet, so normal force end state.
CALL RadioRxCleanup
.Done: MOV A, RADIO_ABORT_SUCCESS
JMP .AbortExit
.2: CALL RadioGetReceiveState
AND A, RXC_IRQ
JZ .2
CALL RadioEndReceive
.AbortExit: PUSH A
MOV X, 0x00 ; Disable abort
MOV A, RX_ABORT_ADR
CALL RadioWrite
POP A
RET
.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
.section
;--------------------------------------------------------------------------------
;
; RadioInterrupt: Manages the radio in an ISR or polling loop.
;
; For interrupt based 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. When using this routine to maintain the
; the radio, the state of that maintainance is communicated to
; the 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.
;
; RadioPoll: Has the same function as RadioInterrupt but causes the RETI
; to simulate a RET by placing a copy of the flag register on
; the stack. This routine can be called (with a CALL or LCALL)
; from a polling loop or an ISR that can not JMP - ie. an ISR
; written in 'C'.
;
; Unlike RadioInterrupt, RadioPoll does not leave the registers
; unaffected.
;
; DO NOT CALL RadioPoll WITH INTERRUPTS DISABLED.
;
; 'C' Call: void RadioInterrupt(void);
;
; Assembly Call: A: Unused
; X: Unused
;
; Assembly Return: A: Untouched
; X: Untouched
;
_RadioPoll::
RadioPoll:: PUSH_F_MESSY ; This stacks the flag shadow.
_RadioInterrupt::
RadioInterrupt:: TST REG[LP_IRQ_Data_ADDR], LP_IRQ_MASK ; Is the interrupt asserted?
JZ .NoRadioInterrupt ; No, just return.
PUSH A ; Save Regs.
PUSH X
;
; RadioGetTransmitState and RadioGetReceiveState both use a set of macros defined
; in irqmacros.inc that use a shadow value of the flags register to allow fast
; IE (interrupt enablement) management. We need to update the shadow value here
; because the ISR clears the real IE.
;
CLEAR_PERM_IE ; Clear the IE shadow.
TST [RadioState], RADIO_TX
JZ .NotReceiving
CALL RadioGetTransmitStateIsr
JMP .RadioIsrDone
.NotReceiving: TST [RadioState], RADIO_RX
JZ .RadioIsrDone
CALL RadioGetReceiveStateIsr
;
; We are now leaving the ISR and need to put the shadow back to it's previous state.
; Since we were in an ISR we know it's state was set. (Interrupts enabled.)
;
.RadioIsrDone: SET_PERM_IE ; Set the IE shadow.
POP X ; Restore Regs.
POP A
.NoRadioInterrupt: RETI
.endsection
;
; Enable the code compressor.
;
ENABLE_CODE_COMPRESSION
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -