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