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

📄 spk208.s

📁 The combined demo is dedicated for S1C33L05, so DMT33L05 should be used to load and run the demo. F
💻 S
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////
//////// Speak.s (Callback Version)
////////
//////// 1998 Oct. 01	inazumi 	Prototype
//////// 1998 Oct. 02	inazumi 	Prototype Ver.2
//////// 1998 Oct. 15	inazumi 	Prototype Ver.2 (Bug Fix)
//////// 1998 Oct. 16	inazumi 	Ver.0.1
//////// 1998 Oct. 28	inazumi 	Ver.0.11	Bug Fix. (SpkOpen)
//////// 1998 Oct. 28	H.Matsuoka	Ver.0.12	for DMT33005 (33208)
//////// 1999 Mar.	8	H.Matsuoka	Ver.0.13	Modify
//////// 1999 Aug. 24	H.Matsuoka	Ver.0.20	PCM15
//////// 1999 Oct. 13	H.Matsuoka	Ver.0.21	PCM15 stereo 
//////// 1999 Nov. 24	H.Matsuoka	Ver.0.22	add 9bit output
//////// 2003 Dec. 03	CH.Yoon 	Ver.0.23	port to GNU33
//////// 2004 Mar. 10	David.ji	Ver.0.24	port to	L05DMT(SEE)
////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include	"slcomm.def"
#include	"slintr.def"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// Global Symbols
//////
		.global SpkInit
		.global SpkOpen
		.global SpkSoftening
		.global SpkSampleRate
		
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// RAM
////// Following "comm" data order can not change.
//////

#define SPK_MAX_CHANNEL_ID		0x02   // ch0, ch1, ch2

 	.section .bss
	.global SPK_PARAMS_0
 	.global SPK_DATA_0
	.align 2

SPK_DATA_0:
 	.zero SIZEOF_CTRL_DATA

SPK_PARAMS_0:
 	.zero SIZEOF_QUEUE_PARAMS

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		.text
		
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// Low-Level Function
//////
        .align  2
SPK_LOW_LEVEL_FUNC_0:		// 10bit PWM, use TM1
		.long	SpkNext
		.long	SpkOpen_0
		.long	SpkStart_0
		.long	SpkHalt_0
		.long	SpkClose_0

SPK_LOW_LEVEL_FUNC_1:		// 15bit PWM,  use TM1 TM0
		.long	SpkNext
		.long	SpkOpen_1
		.long	SpkStart_0
		.long	SpkHalt_0
		.long	SpkClose_1

SPK_LOW_LEVEL_FUNC_2:		// 15bit PWM stereo,  use TM1 TM0 TM5 TM4
		.long	SpkNext
		.long	SpkOpen_2
		.long	SpkStart_0
		.long	SpkHalt_0
		.long	SpkClose_2

SPK_LOW_LEVEL_FUNC_4:		// 9bit PWM,   use TM1 
		.long	SpkNext
		.long	SpkOpen_4
		.long	SpkStart_0
		.long	SpkHalt_0
		.long	SpkClose_0

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////
////// SpkOpen/SpkClose/SpkStart/SpkHalt
//////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define PWM_DUTY_9BIT		0x101
#define PWM_DUTY_10BIT		0x201

//// PWM output port select
#define P2_FUNCTION_SELECT		0x000402d8	// Function select output port

//// PWM output timer0
#define PRESC16_0				0x00040147	// 16bit Timer 0, Prescaler
#define TMCTRL16_0				0x00048186	// 16bit Timer 0
#define COMPARE_A16_0			0x00048180
#define COMPARE_B16_0			0x00048182
#define TIMER16_0_IMASK 		0x00040272

//// PWM output timer1
#define PRESC16_1				0x00040148	// 16bit Timer 1, Prescaler
#define TMCTRL16_1				0x0004818e	// 16bit Timer 1
#define COMPARE_A16_1			0x00048188
#define COMPARE_B16_1			0x0004818a
#define TIMER16_1_IMASK 		0x00040272

//// PWM output timer2
#define PRESC16_2				0x00040149	// 16bit Timer 2, Prescaler
#define TMCTRL16_2				0x00048196	// 16bit Timer 2
#define COMPARE_A16_2			0x00048190
#define COMPARE_B16_2			0x00048192
#define TIMER16_2_IMASK 		0x00040273

//// PWM output timer3
#define PRESC16_3				0x0004014a	// 16bit Timer 3, Prescaler
#define TMCTRL16_3				0x0004819e	// 16bit Timer 3
#define COMPARE_A16_3			0x00048198
#define COMPARE_B16_3			0x0004819a

//// PWM output timer4
#define PRESC16_4				0x0004014b	// 16bit Timer 4, Prescaler
#define TMCTRL16_4				0x000481a6	// 16bit Timer 4
#define COMPARE_A16_4			0x000481a0
#define COMPARE_B16_4			0x000481a2

//// trigger timer
#define SPK_INTR_LEVEL_0		0x06
#define PRESC16_5				0x0004014c	// 16bit Timer 5, Prescaler
#define TMCTRL16_5				0x000481ae	// 16bit Timer 5
#define COMPARE_A16_5			0x000481a8
#define COMPARE_B16_5			0x000481aa
#define TIMER16_5_IMASK 		0x00040274
#define TIMER16_5_IFLAG 		0x00040284
#define TIMER16_5_ILEVEL		0x00040268	// Upper 4-bits


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// BYTE *SpkInit(void)
//////
SpkInit:
		xld.w	%r10,SPK_PARAMS_0
		ld.w	%r11,0x00
		ext 	OFFSET_CSR
		ld.b	[%r10],%r11
		ret

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// BYTE *SpkOpen(int Channel, int ReloadValue)
//////
SpkOpen:
		ld.w	%r10,%r7				// check ReloadValue
		sra 	%r10,0x08
		sra 	%r10,0x08
		jrne	SpkOpenFailed
//
		cmp 	%r6,0x00
		jreq	SpkSetParams_0
		cmp 	%r6,0x01
		jreq	SpkSetParams_1
		cmp 	%r6,0x02
		jreq	SpkSetParams_2
		cmp 	%r6,0x04
		jreq	SpkSetParams_4
		cmp 	%r6,SPK_MAX_CHANNEL_ID
		jrugt	SpkOpenFailed

SpkSetParams_0:
		xld.w	%r6,SPK_PARAMS_0
		xld.w	%r8,SPK_LOW_LEVEL_FUNC_0
		jp		SpkIsOpened
SpkSetParams_1:
		xld.w	%r6,SPK_PARAMS_0
		xld.w	%r8,SPK_LOW_LEVEL_FUNC_1
		jp		SpkIsOpened
SpkSetParams_2:
		xld.w	%r6,SPK_PARAMS_0
		xld.w	%r8,SPK_LOW_LEVEL_FUNC_2
		jp		SpkIsOpened
SpkSetParams_4:
		xld.w	%r6,SPK_PARAMS_0
		xld.w	%r8,SPK_LOW_LEVEL_FUNC_4

SpkIsOpened:
		ext 	OFFSET_CSR
		btst	[%r6],CSR_BITPOS_OPENED
		jrne	SpkOpenFailed
//
		xld.w	%r10,SIZEOF_QUEUE_PARAMS 	// clear Params (Ver.0.11)
		ld.w	%r11,%r6
		ld.w	%r12,0x00
SpkInitLoop:
		ld.w	[%r11]+,%r12
		sub 	%r10,0x04
		jrgt	SpkInitLoop
//
		ext 	OFFSET_LOW_LEVEL_FUNC
		ld.w	[%r6],%r8
		ext 	OFFSET_OPEN
		ld.w	%r4,[%r8]
		call	%r4					// call SpkOpen_0() 
										// dose not destroy r6 - r9 
//
		ext 	OFFSET_CSR
		bset	[%r6],CSR_BITPOS_OPENED
		ret.d
		ld.w	%r4,%r6
//		
SpkOpenFailed:
		ret.d
		ld.w	%r4,0x00	

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// int SpkNext(BYTE *SpkParams)
//////	dose not destroy r8, r6 - r9 
//////	In DMA version, change to control register
//////	   r8  : (*Length)
//////	   r4 : Length
//////	   r6 : SpkParams
//////
SpkNext:
		xcall	QueueRead			// QueueRead dose not destroy r12 - r15
		cmp 	%r4,0x00			// r9:*Length, r10:Length, r11:*Buffer
		jreq	RetSpkNext			// if (Failed) QueueEmpty
		
	// Dynamic change sampling rate
		xld.w	%r11,SPK_SAMPLE_CHANGE_BUF
		ld.w	%r10,[%r11]
		cmp 	%r10,%r5			// %r5 is next buffer
		jrne	NotChangeSample

		ld.w	%r10,-1		  
		ld.w	[%r11],%r10			// clear SPK_SAMPLE_CHANGE_BUF
		xld.w	%r10,SPK_SAMPLERATE
		ld.uh	%r11,[%r10]			// new sampling rate
		xld.w	%r10,COMPARE_B16_5
		ld.h	[%r10],%r11			// set compare B value (ReloadValue)
		xld.w	%r10,TMCTRL16_5
		bset	[%r10],1 			// timer reset
		bset	[%r10],0 			// timer run
		
NotChangeSample:
		ld.w	%r10,%r6
		sub 	%r10,SIZEOF_CTRL_DATA
		ld.w	[%r10]+,%r5 		// HEAD = Buffer
		ld.w	%r11,%r4			// r10 : Length
		sla 	%r11,0x01			// Length * 2 = address size
		add 	%r11,%r5			// 
		ld.w	[%r10],%r11			// TAIL(address) = Buffer(address) + Length
RetSpkNext:
		ret




////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// SpkStart_0
//////
SpkStart_0:
		xld.w	%r11,0x40
   		xld.w	%r10,TIMER16_5_IFLAG
		ld.b   [%r10],%r11	 			// clear comparison B flag
   		xld.w	%r10,TIMER16_5_IMASK
		bset   	[%r10],0x06  			// enable comparison B intr.
//
		xld.w	%r11,0x09			
		xld.w	%r10,PRESC16_5			
		ld.b   	[%r10],%r11 			// Run prescaler 1/2
//
		xld.w	%r10,TMCTRL16_5
		bset	[%r10],1 				// timer reset
		bset	[%r10],0 				// timer run
		ret

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// SpkHalt_0
//////

SpkHalt_0:
		ld.w	%r11,0x0 			
		xld.w	%r10,TMCTRL16_5 	   
		ld.b   	[%r10],%r11 	   		// stop Timer
		xld.w	%r10,PRESC16_5
		ld.b   	[%r10],%r11 	   		// stop prescaler
//
		xld.w	%r10,TIMER16_5_IMASK
		bclr   	[%r10],0x06  			// disable comparison B intr.
		xld.w	%r11,0x40
		xld.w	%r10,TIMER16_5_IFLAG
		ld.b   	[%r10],%r11   			// clear comparison B flag
		ret



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// SpkSampleRate
//////	 Set Sampling rate
//////

	.section .bss
	.align 2

SPK_SAMPLE_CHANGE_BUF:
	.zero 4

SPK_SAMPLERATE:
	.zero 2

	.text

SpkSampleRate:
		ld.w	%r10,%r8				// check ReloadValue
		sra 	%r10,0x08
		sra 	%r10,0x08
		jrne	SpkSampleRateFailed
		xld.h	[SPK_SAMPLERATE],%r8
		xld.w	[SPK_SAMPLE_CHANGE_BUF],%r7
SpkSampleRateFailed:
		ret


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// void SpkSetTimer5()
//////	dose not destroy r6 - r9 
//////
SpkSetTimer5:

		ld.w	%r11,0x00			
		xld.w	%r10, TMCTRL16_5
		ld.b   	[%r10],%r11    		// Timer 	Stop
		xld.w	%r10, PRESC16_5
		ld.b   	[%r10],%r11   		// Prescaler Stop

		xld.w	%r10,COMPARE_B16_5
		ld.h   	[%r10],%r7	 		// set compare B value (ReloadValue)

		xld.w	%r10,TIMER16_5_IMASK
		ld.b	%r11,[%r10]
		and 	%r11,0x3f			
		ld.b	[%r10],%r11			// disable comparison A B intr.

		xld.w	%r5,0x0f			
		xld.w	%r10, TIMER16_5_IFLAG
		ld.b   	[%r10],%r11    		// clear comparison A B factor flags

		xld.w	%r10,TIMER16_5_ILEVEL
		ld.b	%r11,[%r10]
		ld.w	%r12,SPK_INTR_LEVEL_0
		sll 	%r12,0x04
		and 	%r11,0x0f
		or		%r11,%r12
		ld.b	[%r10],%r11			// set interrupt level
	ret 


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// void SpkOpen_0(BYTE *SpkParams, int ReloadValue)
//////	dose not destroy r6 - r9 
//////	for 10bit PWM
SpkOpen_0:

		xcall SpkSetTimer5			// set trigger timer

//
//	PWM start TM1
//
		ld.w	%r11,0x00			
		xld.w	%r10, TMCTRL16_1
		ld.b   	[%r10],%r11    		// Timer16_1 stop
		xld.w	%r10, PRESC16_1
		ld.b   	[%r10],%r11   		// stop prescaler

		xld.w	%r10,TIMER16_1_IMASK
		bclr	[%r10],0x06			// disable comparison B intr.
		bclr	[%r10],0x07			// disable comparison A intr.

		xld.w	%r11, PWM_DUTY_10BIT // for 10bit PWM
		xld.w	%r10,COMPARE_B16_1
		ld.h   	[%r10],%r11 		// Reload value for timer fine mode

		xld.w	 %r11,0x0			
		xld.w	%r10,COMPARE_A16_1
		ld.h   	[%r10],%r11 		// first PWM output data

		xld.w	%r11,0x8 			
		xld.w	%r10,PRESC16_1
		ld.b   	[%r10],%r11 		// prescaler clock on, 1/1

		xld.w	%r10,TMCTRL16_1		// set Timer16
		bset	[%r10],6 			// fine mode on
		bset	[%r10],5 			// comparison buffer on
		bset	[%r10],4 			// output invert
		bset	[%r10],2 			// output
		bset	[%r10],1 			// reset
		bset	[%r10],0 			// run

		xld.w	%r10,P2_FUNCTION_SELECT
		bset   	[%r10],0x3	  		// P port change to timer output

		xld.h	[SPK_SAMPLERATE],%r7
		xld.w	[SPK_SAMPLE_CHANGE_BUF],%r6 // buffer init SpkParams

		xld.w	%r12,COMPARE_A16_1	// set argument
		xld.w	%r13,PWM_DUTY_10BIT
		xcall	SpkSoftOpen

		ret



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// void SpkOpen_1(BYTE *SpkParams, int ReloadValue)
//////	dose not destroy r6 - r9 
//////	for 15bit PWM
//////
SpkOpen_1:

		xcall SpkSetTimer5		// set trigger timer

//
//	PWM start TM1 Main
//
		ld.w	%r11,0x00			

⌨️ 快捷键说明

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