📄 spk208.s
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////
//////// 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 + -