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

📄 voip8kisr.asm

📁 Cypress 的VOIP DEMO 研究VOIP终端的朋友可以研究研究
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	JZ	.exit			; Radio buffer empty, nothing to do
	MOV	X, A			; X = length to load
	; ------------------------------
	CMP	A, MAX_CTL_SZ+1
	JC	.ctl			; Small "control" frame
	; ------------------------------
	CMP	A, VOIP_PKT_LEN
	JNZ	.trash			; Discard: not Control or ADPCM

	; ------------------------------
	; ADPCM Frame
	; ------------------------------
.voip:
	CMP	[rxPktStat], RXPKT_TRASH ; If already loaded ADPCM frame,
	JZ	.trash			 ;  then discard buffer
	MOV	[rxVoipSet], [RadioWipPtr]
	CALL	isrRadioFileReadWip	; Unload ADPCM data from Radio
	JMP	.exit

	; ------------------------------
	; Control Frame
	; ------------------------------
.ctl:	MOV	[_bufRxCtl+0], X		; Length of buffer
	MOV	[RadioWipPtr], _bufRxCtl+1
	CALL	isrRadioFileReadWip	; Unload Control frame from Radio
	JMP	.exit

	; --------------------------------------------------------------------
	; Discard frame (corrupt or duplicate frames)
	; --------------------------------------------------------------------
.trash:	CALL	isrRadioFileReadWipTrash ; Unload data from Radio and discard

	; --------------------------------------------------------------------
	; If Tx Go was skipped, force radio to RX mode
	; --------------------------------------------------------------------
	MOV	A, [txGoSkipped]
	JZ	.exit
	MOV	X, (FRC_END_STATE + END_STATE_RX)
	MOV	A, XACT_CFG_ADR + bSPI_WRITE
	CALL	isrRadioWrite
		; Don't wait for FRC_END_STATE to complete, just delay
		;  by waiting for next ISR to issue more SPI commands
	; fallthru JMP	.exit

	; --------------------------------------------------------------------
	; If Slot 4A, then publish result of ADPCM Radio load
	;
	; rxVoipSet = 0 if failed to load ADPCM from radio
	;           = bufRxVoip0 or bufRxVoip1
	; --------------------------------------------------------------------
.exit:
	CMP	[_slotCt], 4+12		;
	JNZ	isrRadX			; Not Tx_4b slot, so not 3 mS epoch

	; --------------------------------------------------------------------
	; Update Rx Voip Fast Packet Average (assume missed packet)
	; --------------------------------------------------------------------
	MOV	A, [_rxPktAve_Q3]	; Ant A/B packet average
	ASR	A			;
	ASR	A			;
	ASR	A			;
	AND	A, 0x1F			;
	SUB	[_rxPktAve_Q3], A	; Default missed-packet
	; --------------------------------------------------------------------
	; Update Rx Voip Slow Packet Average (assume missed packet)
	; --------------------------------------------------------------------
	MOV	A, [_rxPktAve_Q8+MSB]	; Ant A/B packet average
	SUB	[_rxPktAve_Q8+LSB], A	; Default missed-packet
	SBB	[_rxPktAve_Q8+MSB], 0	;
	; -------------------------------

	XOR	[bufRxVoipTog], 1	; Alternate RAM buffers for Rx packets

	MOV	A, [rxVoipSet]		; Load and Test for ZERO
	MOV	[rxVoipSet], 0		; Haven't loaded *new* VOIP frame yet
	MOV	[bufRxVoipPtr], A
	JZ	.noRx			; <<<< No RF frame, bufRxVoipPtr=0 >>>

	; --------------------------------------------------------------------
	; Publish results of valid received 3 mS voice packet.
	; --------------------------------------------------------------------
	ADD	[_rxPktAve_Q3], 15	; Update Fast Rx Packet Average
	ADD	[_rxPktAve_Q8+LSB], 127	; Update Slow Rx Packet Average
	ADC	[_rxPktAve_Q8+MSB], 0	;

	ADD	[bufRxVoipPtr], 3	; Ptr to ADPCM samples

  IF	LOOPBACK_ADPCM		;#############################################
	; Let ADPCM predict and step free-run				;#####
  ELSE	; NOT LOOPBACK_ADPCM	;#############################################
	MOV	X, A			; rxVoipSet[0]
	MOV	A, [X+MSB]
	AND	A, 0x0F			; prediction is only 12-bits
	MOV	[_iDecPredict+MSB], A	; MSByte
	MOV	A, [X+LSB]
	; --------------------------------------------------------------------
	; Convert 12-bit Prediction from RF to 15-bit prediction for local use
	; --------------------------------------------------------------------
	ASL	A			; (MSB,LSB) <<= 3
	RLC	[_iDecPredict+MSB]
	ASL	A			; LSByte
	RLC	[_iDecPredict+MSB]
	ASL	A			; LSByte
	RLC	[_iDecPredict+MSB]
	MOV	[_iDecPredict+LSB], A	; LSByte

	MOV	A, [X+2]
	MOV	[_bDecStepSizePtr], A
  ENDIF	; LOOPBACK_ADPCM	;#############################################
	JMP	isrRadX

.noRx:
	INC_16	_mibMissRx_2
	JMP	isrRadX


; ----------------------------------------------------------------------------
doFrameTx_6a:
	UART_BIT
	JMP	isrRadX
; ----------------------------------------------------------------------------

; ----------------------------------------------------------------------------
;
; doFrameRx_1 - 
;
; ----------------------------------------------------------------------------
doFrameRx_1:
	MOV	A, [_reqChWrite]	; If new voice channel pending
	JNZ	doChChg1		;  then begin changing channel
					; Else proceed with normal receive
	; ---------- RX_GO
	MOV	X, (RX_GO + SOFDET_IRQ + RXC_IRQ)
	MOV	A, RX_CTRL_ADR + bSPI_WRITE
	CALL	isrRadioWrite

	; ---------- WORKAROUND: FALSE SOP IMMEDIATELY AFTER RX_GO
	MOV	A, RX_IRQ_STATUS_ADR	; Clear any false SOP bit from RX_GO
	CALL	isrRadioRead		;  When radio isn't IDLE, if this
	MOV	[rxGoOn], 1		;  occurs, it *just* occurred.
	MOV	[rxIrqStatus], 0

	; ---------- goto Tx mode if frame received
	MOV	X, END_STATE_TXSYNTH
	MOV	A, XACT_CFG_ADR + bSPI_WRITE
	CALL	isrRadioWrite

	JMP	isrRadX

; ----------------------------------------------------------------------------
;
; doFrameRx_2a - Decide whether SOP is arriving where it should
; doFrameRx_2b - Decide whether SOP is arriving where it should
;
; ----------------------------------------------------------------------------
doFrameRx_2a:
	UART_BIT

doFrameRx_2b:
	MOV	[rxPktStat], RXPKT_VOIP	; Default to Found SOP for VOIP frame
	; --------------------------------------------------------------------
	; ADJUST SLOT TIMING TO TRACK ARRIVING FRAMES
	; 
	; Align SOP at this point (about 30 uS from ISR)
	; --------------------------------------------------------------------
	TEST_LED_LO	; =======================
	TEST_LED_HI	; =======================
	IS_IRQ_ON
	jnz	.early
	; --------------------------------------------------------------------
	; If SOP doesn't arrive in 20 uS, then begin Rx Abort process
	; --------------------------------------------------------------------
.sopWait:
	MOV	A, (20 * CPU_MHZ/23)	; Wait max 20uS
.wait:	IS_IRQ_ON			; 9
	JNZ	.late			; 5 GOOD: SOP arrived
	DEC	A			; 4
	JNZ	.wait			; 5

.sopFail:
	; --------------------------------------------------------------------
	; SOP FAILED - Start Rx ABORT process via CDT4056 WORKAROUND
	; --------------------------------------------------------------------
	MOV	X, ABORT_EN
	MOV	A, RX_ABORT_ADR + bSPI_WRITE
	CALL	isrRadioWrite
	MOV	[rxPktStat], RXPKT_NOSOP ; Mark bad Rx slot
	INC_16	_mibMissRx_1		; ++ error count
	JMP	isrRadX
	; --------------------------------------------------------------------

.early:	MOV	[isrPeriod], ISR_VAL_NEG1 ; Early SOP = Faster Counter
	jmp	.exit
.late:	MOV	[isrPeriod], ISR_VAL_POS1 ; Late SOP = Slower Counter

.exit:	MOV	A, RX_IRQ_STATUS_ADR	;
       	CALL	isrRadioRead		; Expose RXC/RXE IRQ
	MOV	[rxIrqStatus], A	; and remember any self-clearing flags
	JMP	isrRadX

; ----------------------------------------------------------------------------
;
; doFrameRx_3 -
;
; ----------------------------------------------------------------------------
doFrameRx_3a:
	UART_BIT
doFrameRx_3b:
	MOV	[isrPeriod], ISR_VAL_NOM ; Clr possible adj from doFrameRx_2
	CMP	[rxPktStat], RXPKT_NOSOP ; If SOP was present
	JNZ	isrRadX			;   then don't abort the Rx

	; --------------------------------------------------------------------
	; No Rx Frame arrived in designated Slot, therefore Rx is 
	;  manually being aborted by using digital loopback.
	; --------------------------------------------------------------------
	; although RadioAbort() uses SOP bit in RSSI register, this isn't any
	;  better than using SOP_IRQ.  I've seen SOP_IRQ be falsely set, then
	;  cleared by this firmware, and subsequently SOP_RSSI is seen here.
	;  So... forget RadioAbort() and just use SOP_IRQ
	; --------------------------------------------------------------------
	IS_IRQ_ON
	JZ	frcEnd			; No SOP, Force End State is OK now

	MOV	A, RX_IRQ_STATUS_ADR	;
	call	isrRadioRead		; Expose RXC/RXE IRQ
	OR	[rxIrqStatus], A	; and remember any self-clearing flags
	JMP	digLbOff

	
	; --------------------------------------------------------------------
	; No SOP yet (and we're not going to get one because digital loopback)
	; So Force End State is safe.
	; --------------------------------------------------------------------
frcEnd:
	MOV	X, (FRC_END_STATE + END_STATE_TXSYNTH)
	MOV	A, XACT_CFG_ADR + bSPI_WRITE
	CALL	isrRadioWrite
.Loop:	MOV	A, XACT_CFG_ADR		; Wait for the FRC_END_STATE
	CALL	isrRadioRead		;  bit in the XACT_CFG register
	AND	A, FRC_END_STATE	;  to clear indicating the force has
	JNZ	.Loop			;  completed.

	MOV	[rxGoOn], 0		; Rx Go is finally finished

digLbOff:
	MOV	X, 0x00			; Disble digital loopback (normal mode)
	MOV	A, RX_ABORT_ADR + bSPI_WRITE
	CALL	isrRadioWrite

	JMP	isrRadX
; ----------------------------------------------------------------------------

; ----------------------------------------------------------------------------
;
; doFrameRx_5a - 
; doFrameRx_5b - 
;
; ----------------------------------------------------------------------------
doFrameRx_5b:
	; --------------------------------------------------------------------
	; Prep to load Load VOIP Tx Slot A: Always a new VOIP frame
	; --------------------------------------------------------------------
	MOV	[txPktLen], VOIP_PKT_LEN
	MOV	[RadioWipPtr], bufTxVoip
	
	MOV	X, TX_CLR		; ---------- Clear Tx Buffer
	MOV	A, TX_CTRL_ADR + bSPI_WRITE
	CALL	isrRadioWrite

	INC_16	_voipCt

	JMP	isrRadX

; ----------------------------------------------------------------------------
; Load VOIP Tx Slot B: Usually retransmit VOIP_A frame, or new control frame
; ----------------------------------------------------------------------------
doFrameRx_5a:
	UART_BIT

	MOV	A, [bufTxCtl]
	JZ	isrRadX			; Just retransmit VOIP_A frame

	MOV	[txPktLen], A 		; Control frame Length
	MOV	X, TX_CLR		; ---------- Clear Tx Buffer
	MOV	A, TX_CTRL_ADR + bSPI_WRITE
	CALL	isrRadioWrite
	JMP	isrRadX

; ----------------------------------------------------------------------------
;
; doFrameRx_6a - 
;
;						FINAL SLOT BEFORE REPEAT
; doFrameRx_6b - Should have (nearly) finished receiving frame
;
; ----------------------------------------------------------------------------
doFrameRx_6b:

	MOV	[_slotCt], 0		; wraparound slot counter [1-24]

	; --------------------------------------------------------------------
	;
	; ---------- Copy VOIP frame to Radio Tx buf
	;
	; --------------------------------------------------------------------
	MOV	A, TX_BUFFER_ADR + bSPI_WRITE
	CALL	isrRadioFileWriteWip	; Burst the data in


	; --------------------------------------------------------------------
	; Reset local ADPCM Encode buffer
	;
	; Snapshot of ADPCM Encoder state
	; --------------------------------------------------------------------
	MOV	[bufTxVoipPtr], bufTxVoip+3	; New ADPCM samples go here

	MOV	[bufTxVoip+2],   [_bEncStepSizePtr]	; Enc StepSize

	MOV	[bufTxVoip+LSB], [_iEncPredict+LSB]
	MOV	A,               [_iEncPredict+MSB]	; Enc Predict (15-bit)
	RRC	A			; (MSB,LSB) >>= 3
	RRC	[bufTxVoip+LSB]
	RRC	A			; (MSB,LSB) >>= 3
	RRC	[bufTxVoip+LSB]
	RRC	A			; (MSB,LSB) >>= 3
	RRC	[bufTxVoip+LSB]
	AND	A, 0x0F
	MOV	[bufTxVoip+MSB], A	; Enc Predict (12-bit)
	; ------------------------------
	JMP	isrRadX

doFrameRx_6a:
	CMP	[txPktLen], VOIP_PKT_LEN
	JZ	isrRadX			; Resend prior VOIP frame

	; --------------------------------------------------------------------
	; ---------- Copy Control frame to Radio Tx buf
	; --------------------------------------------------------------------
	MOV	[RadioWipPtr], bufTxCtl + 1	; ptr to Control frame data
	MOV	[bufTxCtl], 0		; Indicate control buf has been sent
	MOV	A, TX_BUFFER_ADR + bSPI_WRITE
	CALL	isrRadioFileWriteWip	; Burst the data in
	JMP	isrRadX

isrRadX:
	; --------------------------------------------------------------------
	;
	; ADPCM PROCESSING
	;
	; Get 15-bit unipolar big-endian word from USB OUT page buffer
	;
	; Also do USB to Codec rate-matching here (sample insert/delete),
	;  based on 
	; If bit 15 is SET in [[usbOutOt]], then either INSERT or DELETE sample
	;  	insert [insertVal], clearing [15] in [usbOutOt] for next time
	;	delete skip by simply ++usbOutOt.
	; 	extern char nulInsDel = Pending: {0=none, 1=insert, 2=delete}
	; 	extern WORD insertVal = 15-bit unipolar
	; ---------------------------------------------------------------------
	MOV	A, [_usbOutOt+LSB]

⌨️ 快捷键说明

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