1
2 #include <platform_stdlib.h>
3 #include <math.h>
4 #include "rl6548.h"
5 #include "audio_internel.h"
6 #include "osdep_service.h"
7
8 //#define ENABLE_PA
9
10 static u8 sp_rx_buf[SP_DMA_PAGE_SIZE * SP_DMA_PAGE_NUM]__attribute__((aligned(32)));
11 static u8 sp_tx_buf[SP_DMA_PAGE_SIZE * SP_DMA_PAGE_NUM]__attribute__((aligned(32)));
12 static u8 sp_zero_buf[SP_ZERO_BUF_SIZE]__attribute__((aligned(32)));
13 static u8 sp_full_buf[SP_FULL_BUF_SIZE]__attribute__((aligned(32)));
14
15 static u8 rx_data_cache[SP_DMA_PAGE_SIZE];
16 static uint32_t rx_data_cache_len = 0;
17
18
19 static SP_InitTypeDef SP_InitStruct;
20 static SP_GDMA_STRUCT SPGdmaStruct;
21 static SP_OBJ sp_obj;
22 static SP_RX_INFO sp_rx_info;
23 static SP_TX_INFO sp_tx_info;
24 static int RX_GDMA_flag = 0; //0, start, 1, stop, 2, close
25 static int TX_GDMA_flag = 0;
26 static SP_OBJ sp_obj;
27 static SP_InitTypeDef SP_InitStruct;
28
29 extern void PLL_Div(u32 div);
30 extern BOOL AUDIO_SP_TXGDMA_Restart(u8 GDMA_Index, u8 GDMA_ChNum, u32 tx_addr, u32 tx_length);
31 extern BOOL AUDIO_SP_RXGDMA_Restart(u8 GDMA_Index, u8 GDMA_ChNum, u32 rx_addr, u32 rx_length);
32
sp_get_free_tx_page(void)33 static u8 *sp_get_free_tx_page(void)
34 {
35 pTX_BLOCK ptx_block = &(sp_tx_info.tx_block[sp_tx_info.tx_usr_cnt]);
36
37 if (ptx_block->tx_gdma_own)
38 return NULL;
39 else{
40 return (u8*)ptx_block->tx_addr;
41 }
42 }
43
sp_write_tx_page(u8 * src,u32 length)44 static void sp_write_tx_page(u8 *src, u32 length)
45 {
46 pTX_BLOCK ptx_block = &(sp_tx_info.tx_block[sp_tx_info.tx_usr_cnt]);
47
48 memcpy((void*)ptx_block->tx_addr, src, length);
49 ptx_block-> tx_gdma_own = 1;
50 ptx_block -> tx_length = length;
51 sp_tx_info.tx_usr_cnt++;
52 if (sp_tx_info.tx_usr_cnt == SP_DMA_PAGE_NUM){
53 sp_tx_info.tx_usr_cnt = 0;
54 }
55 }
56
sp_release_tx_page(void)57 static void sp_release_tx_page(void)
58 {
59 pTX_BLOCK ptx_block = &(sp_tx_info.tx_block[sp_tx_info.tx_gdma_cnt]);
60
61 if (sp_tx_info.tx_empty_flag){
62 }
63 else{
64 ptx_block->tx_gdma_own = 0;
65 sp_tx_info.tx_gdma_cnt++;
66 if (sp_tx_info.tx_gdma_cnt == SP_DMA_PAGE_NUM){
67 sp_tx_info.tx_gdma_cnt = 0;
68 }
69 }
70 }
71
sp_get_ready_tx_page(void)72 static u8 *sp_get_ready_tx_page(void)
73 {
74 pTX_BLOCK ptx_block = &(sp_tx_info.tx_block[sp_tx_info.tx_gdma_cnt]);
75
76 if (ptx_block->tx_gdma_own){
77 sp_tx_info.tx_empty_flag = 0;
78 return (u8*)ptx_block->tx_addr;
79 }
80 else{
81 sp_tx_info.tx_empty_flag = 1;
82 return (u8*)sp_tx_info.tx_zero_block.tx_addr; //for audio buffer empty case
83 }
84 }
85
sp_get_ready_tx_length(void)86 static u32 sp_get_ready_tx_length(void)
87 {
88 pTX_BLOCK ptx_block = &(sp_tx_info.tx_block[sp_tx_info.tx_gdma_cnt]);
89
90 if (sp_tx_info.tx_empty_flag){
91 return sp_tx_info.tx_zero_block.tx_length;
92 }
93 else{
94 return ptx_block->tx_length;
95 }
96 }
97
sp_tx_complete(void * Data)98 static void sp_tx_complete(void *Data)
99 {
100 SP_GDMA_STRUCT *gs = (SP_GDMA_STRUCT *) Data;
101 PGDMA_InitTypeDef GDMA_InitStruct;
102 u32 tx_addr;
103 u32 tx_length;
104
105 GDMA_InitStruct = &(gs->SpTxGdmaInitStruct);
106
107 /* Clear Pending ISR */
108 GDMA_ClearINT(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum);
109 sp_release_tx_page();
110 tx_addr = (u32)sp_get_ready_tx_page();
111 tx_length = sp_get_ready_tx_length();
112 if(TX_GDMA_flag == 0) {
113 AUDIO_SP_TXGDMA_Restart(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, tx_addr, tx_length);
114 } else {
115 GDMA_ChnlFree(SPGdmaStruct.SpTxGdmaInitStruct.GDMA_Index, SPGdmaStruct.SpTxGdmaInitStruct.GDMA_ChNum);
116 AUDIO_SP_TdmaCmd(AUDIO_SPORT_DEV, DISABLE);
117 // AUDIO_SP_TxStart(AUDIO_SPORT_DEV, DISABLE);
118
119 if(TX_GDMA_flag == 2){
120 RCC_PeriphClockCmd(APBPeriph_AUDIOC, APBPeriph_AUDIOC_CLOCK, DISABLE);
121 RCC_PeriphClockCmd(APBPeriph_SPORT, APBPeriph_SPORT_CLOCK, DISABLE);
122 CODEC_DeInit(APP_LINE_OUT);
123 PLL_PCM_Set(DISABLE);
124 }
125 }
126 }
127
sp_get_ready_rx_page(void)128 static u8 *sp_get_ready_rx_page(void)
129 {
130 pRX_BLOCK prx_block = &(sp_rx_info.rx_block[sp_rx_info.rx_usr_cnt]);
131
132 if (prx_block->rx_gdma_own)
133 return NULL;
134 else{
135 return (u8 *)prx_block->rx_addr;
136 }
137 }
138
sp_read_rx_page(u8 * dst,u32 length)139 static void sp_read_rx_page(u8 *dst, u32 length)
140 {
141 pRX_BLOCK prx_block = &(sp_rx_info.rx_block[sp_rx_info.rx_usr_cnt]);
142
143 memcpy(dst, (u8 *)prx_block->rx_addr, length);
144 prx_block->rx_gdma_own = 1;
145 sp_rx_info.rx_usr_cnt++;
146 if (sp_rx_info.rx_usr_cnt == SP_DMA_PAGE_NUM){
147 sp_rx_info.rx_usr_cnt = 0;
148 }
149 }
150
151
sp_release_rx_page(void)152 static void sp_release_rx_page(void)
153 {
154 pRX_BLOCK prx_block = &(sp_rx_info.rx_block[sp_rx_info.rx_gdma_cnt]);
155
156 if (sp_rx_info.rx_full_flag){
157 }
158 else{
159 prx_block->rx_gdma_own = 0;
160 sp_rx_info.rx_gdma_cnt++;
161 if (sp_rx_info.rx_gdma_cnt == SP_DMA_PAGE_NUM){
162 sp_rx_info.rx_gdma_cnt = 0;
163 }
164 }
165 }
166
167
sp_get_free_rx_page(void)168 static u8 *sp_get_free_rx_page(void)
169 {
170 pRX_BLOCK prx_block = &(sp_rx_info.rx_block[sp_rx_info.rx_gdma_cnt]);
171
172 if (prx_block->rx_gdma_own){
173 sp_rx_info.rx_full_flag = 0;
174 return (u8 *)prx_block->rx_addr;
175 }
176 else{
177 sp_rx_info.rx_full_flag = 1;
178 return (u8 *)sp_rx_info.rx_full_block.rx_addr; //for audio buffer full case
179 }
180 }
181
sp_get_free_rx_length(void)182 static u32 sp_get_free_rx_length(void)
183 {
184 pRX_BLOCK prx_block = &(sp_rx_info.rx_block[sp_rx_info.rx_gdma_cnt]);
185
186 if (sp_rx_info.rx_full_flag){
187 return sp_rx_info.rx_full_block.rx_length;
188 }
189 else{
190 return prx_block->rx_length;
191 }
192 }
193
sp_init_tx_variables(void)194 static void sp_init_tx_variables(void)
195 {
196 int i;
197
198 for(i=0; i<SP_ZERO_BUF_SIZE; i++){
199 sp_zero_buf[i] = 0;
200 }
201 sp_tx_info.tx_zero_block.tx_addr = (u32)sp_zero_buf;
202 sp_tx_info.tx_zero_block.tx_length = (u32)SP_ZERO_BUF_SIZE;
203
204 sp_tx_info.tx_gdma_cnt = 0;
205 sp_tx_info.tx_usr_cnt = 0;
206 sp_tx_info.tx_empty_flag = 0;
207
208 for(i=0; i<SP_DMA_PAGE_NUM; i++){
209 sp_tx_info.tx_block[i].tx_gdma_own = 0;
210 sp_tx_info.tx_block[i].tx_addr = (u32)sp_tx_buf+i*SP_DMA_PAGE_SIZE;
211 sp_tx_info.tx_block[i].tx_length = SP_DMA_PAGE_SIZE;
212 }
213 }
214
sp_init_rx_variables(void)215 static void sp_init_rx_variables(void)
216 {
217 int i;
218 sp_rx_info.rx_full_block.rx_addr = (u32)sp_full_buf;
219 sp_rx_info.rx_full_block.rx_length = (u32)SP_FULL_BUF_SIZE;
220
221 sp_rx_info.rx_gdma_cnt = 0;
222 sp_rx_info.rx_usr_cnt = 0;
223 sp_rx_info.rx_full_flag = 0;
224
225 for(i=0; i<SP_DMA_PAGE_NUM; i++){
226 sp_rx_info.rx_block[i].rx_gdma_own = 1;
227 sp_rx_info.rx_block[i].rx_addr = (u32)(sp_rx_buf + i*SP_DMA_PAGE_SIZE);
228 sp_rx_info.rx_block[i].rx_length = SP_DMA_PAGE_SIZE;
229 }
230 }
231
sp_rx_complete(void * data)232 static void sp_rx_complete(void *data)
233 {
234 SP_GDMA_STRUCT *gs = (SP_GDMA_STRUCT *) data;
235 PGDMA_InitTypeDef GDMA_InitStruct;
236 u32 rx_addr;
237 u32 rx_length;
238 char *pbuf;
239
240 GDMA_InitStruct = &(gs->SpRxGdmaInitStruct);
241 DCache_Invalidate(GDMA_InitStruct->GDMA_DstAddr, GDMA_InitStruct->GDMA_BlockSize<<2);
242 /* Clear Pending ISR */
243 GDMA_ClearINT(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum);
244 sp_release_rx_page();
245 rx_addr = (u32)sp_get_free_rx_page();
246 rx_length = sp_get_free_rx_length();
247
248 if(RX_GDMA_flag == 0) {
249 AUDIO_SP_RXGDMA_Restart(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, rx_addr, rx_length);
250 } else {
251 GDMA_ChnlFree(SPGdmaStruct.SpRxGdmaInitStruct.GDMA_Index, SPGdmaStruct.SpRxGdmaInitStruct.GDMA_ChNum);
252 AUDIO_SP_RdmaCmd(AUDIO_SPORT_DEV, DISABLE);
253 // AUDIO_SP_RxStart(AUDIO_SPORT_DEV, DISABLE);
254
255 if(RX_GDMA_flag == 2) {
256 RCC_PeriphClockCmd(APBPeriph_AUDIOC, APBPeriph_AUDIOC_CLOCK, DISABLE);
257 RCC_PeriphClockCmd(APBPeriph_SPORT, APBPeriph_SPORT_CLOCK, DISABLE);
258 CODEC_DeInit(APP_AMIC_IN);
259 PLL_PCM_Set(DISABLE);
260 }
261 }
262 }
263
sp_init_hal(pSP_OBJ psp_obj)264 static void sp_init_hal(pSP_OBJ psp_obj)
265 {
266 u32 div;
267 PLL_I2S_Set(ENABLE); //enable 98.304MHz PLL. needed if fs=8k/16k/32k/48k/96k
268 //PLL_PCM_Set(ENABLE); //enable 45.1584MHz PLL. needed if fs=44.1k/8.2k
269
270 RCC_PeriphClockCmd(APBPeriph_AUDIOC, APBPeriph_AUDIOC_CLOCK, ENABLE);
271 RCC_PeriphClockCmd(APBPeriph_SPORT, APBPeriph_SPORT_CLOCK, ENABLE);
272
273 //set clock divider to gen clock sample_rate*256 from 98.304M.
274 switch(psp_obj->sample_rate){
275 case SR_48K:
276 div = 8;
277 break;
278 case SR_96K:
279 div = 4;
280 break;
281 case SR_32K:
282 div = 12;
283 break;
284 case SR_16K:
285 div = 24;
286 break;
287 case SR_8K:
288 div = 48;
289 break;
290 default:
291 DBG_8195A("sample rate not supported!!\n");
292 break;
293 }
294 PLL_Div(div);
295
296 PAD_CMD(_PA_0, DISABLE);
297 PAD_CMD(_PA_1, DISABLE);
298 PAD_CMD(_PA_2, DISABLE);
299 PAD_CMD(_PA_3, DISABLE);
300 PAD_CMD(_PA_4, DISABLE);
301
302 PAD_CMD(_PB_28, DISABLE);
303 PAD_CMD(_PB_29, DISABLE);
304 PAD_CMD(_PB_30, DISABLE);
305 PAD_CMD(_PB_31, DISABLE);
306
307 /*codec init*/
308 CODEC_Init(psp_obj->sample_rate, psp_obj->word_len, psp_obj->mono_stereo, psp_obj->direction);
309
310
311 #ifdef ENABLE_PA
312 CODEC_SetAmicBst(0x3, 0x1); //right loopback
313 CODEC_SetVolume(0x82, 0x82);
314
315 u32 reg_value = 0;
316 reg_value = AUDIO_SI_ReadReg(0x2);
317 //reg_value &= ~(15<<BIT_MICBST_GSELL);
318 reg_value |= (1<<14);
319 AUDIO_SI_WriteReg(0x2, reg_value);
320 #else
321 CODEC_SetAmicBst(0x3, 0x3);
322 CODEC_SetVolume(0x92, 0x92);
323 #endif
324 }
325
326 // static
rl6548_capture_start()327 void rl6548_capture_start()
328 {
329 u32 rx_addr;
330 u32 rx_length;
331 RX_GDMA_flag = 0;
332 memset(rx_data_cache, 0x00, SP_DMA_PAGE_SIZE);
333 rx_data_cache_len = 0;
334
335 sp_init_rx_variables();
336 // AUDIO_SP_Init(AUDIO_SPORT_DEV, &SP_InitStruct);
337 AUDIO_SP_RdmaCmd(AUDIO_SPORT_DEV, ENABLE);
338 AUDIO_SP_RxStart(AUDIO_SPORT_DEV, ENABLE);
339
340 rx_addr = (u32)sp_get_free_rx_page();
341 rx_length = sp_get_free_rx_length();
342 AUDIO_SP_RXGDMA_Init(0, &SPGdmaStruct.SpRxGdmaInitStruct, &SPGdmaStruct, (IRQ_FUN)sp_rx_complete, (u8 *)rx_addr, rx_length);
343 }
344
345 // static
rl6548_capture_stop()346 void rl6548_capture_stop()
347 {
348 RX_GDMA_flag = 1;
349 }
350
351 // static
rl6548_playback_start()352 void rl6548_playback_start()
353 {
354 u32 tx_addr;
355 u32 tx_length;
356
357 TX_GDMA_flag = 0;
358
359 sp_init_tx_variables();
360 // AUDIO_SP_Init(AUDIO_SPORT_DEV, &SP_InitStruct);
361 AUDIO_SP_TdmaCmd(AUDIO_SPORT_DEV, ENABLE);
362 AUDIO_SP_TxStart(AUDIO_SPORT_DEV, ENABLE);
363
364 tx_addr = (u32)sp_get_ready_tx_page();
365 tx_length = sp_get_ready_tx_length();
366 AUDIO_SP_TXGDMA_Init(0, &SPGdmaStruct.SpTxGdmaInitStruct, &SPGdmaStruct, (IRQ_FUN)sp_tx_complete, (u8 *)tx_addr, tx_length);
367 }
368
369 // static
rl6548_playback_stop()370 void rl6548_playback_stop()
371 {
372 TX_GDMA_flag = 1;
373 }
374
375
rl6548_audio_init(int sampleRate,int channels,int wordLen)376 void *rl6548_audio_init(int sampleRate, int channels, int wordLen)
377 {
378 // printf("enter rl6548_audio_init\n");
379 pSP_OBJ psp_obj = &sp_obj;
380
381 if(channels == 1)
382 psp_obj->mono_stereo= CH_MONO;
383 else if(channels == 2)
384 psp_obj->mono_stereo= CH_STEREO;
385
386 psp_obj->word_len = wordLen;
387
388 switch(sampleRate) {
389 case 48000:
390 psp_obj->sample_rate = SR_48K;
391 break;
392 case 96000:
393 psp_obj->sample_rate = SR_96K;
394 break;
395 case 32000:
396 psp_obj->sample_rate = SR_32K;
397 break;
398 case 16000:
399 psp_obj->sample_rate = SR_16K;
400 break;
401 case 8000:
402 psp_obj->sample_rate = SR_8K;
403 break;
404 case 44100:
405 psp_obj->sample_rate = SR_44P1K;
406 break;
407 case 88200:
408 psp_obj->sample_rate = SR_88P2K;
409 break;
410 default:
411 printf("not support sr %d\n", sampleRate);
412 }
413
414 psp_obj->direction = APP_AMIC_IN | APP_LINE_OUT; //default
415
416 sp_init_hal(psp_obj);
417 sp_init_rx_variables();
418 sp_init_tx_variables();
419
420 /*configure Sport according to the parameters*/
421 AUDIO_SP_StructInit(&SP_InitStruct);
422 SP_InitStruct.SP_MonoStereo= psp_obj->mono_stereo;
423 SP_InitStruct.SP_WordLen = psp_obj->word_len;
424
425 AUDIO_SP_Init(AUDIO_SPORT_DEV, &SP_InitStruct);
426 return psp_obj;
427 }
428
429
rl6548_audio_deinit()430 void rl6548_audio_deinit()
431 {
432 // printf("enter rl6548_audio_deinit\n");
433 RCC_PeriphClockCmd(APBPeriph_AUDIOC, APBPeriph_AUDIOC_CLOCK, DISABLE);
434 RCC_PeriphClockCmd(APBPeriph_SPORT, APBPeriph_SPORT_CLOCK, DISABLE);
435 CODEC_DeInit(APP_AMIC_IN | APP_LINE_OUT);
436 PLL_PCM_Set(DISABLE);
437 }
438
439
rl6548_audio_write(void * h,uint8_t * buf,uint32_t size)440 int rl6548_audio_write(void *h, uint8_t *buf, uint32_t size)
441 {
442 uint32_t offset = 0;
443 uint32_t tx_len;
444
445 while(size) {
446 if (sp_get_free_tx_page()){
447 tx_len = (size >= SP_DMA_PAGE_SIZE) ? SP_DMA_PAGE_SIZE : size;
448 sp_write_tx_page((buf+offset), tx_len);
449 offset += tx_len;
450 size -= tx_len;
451 } else {
452 // rtw_msleep_os(1);
453 aos_msleep(1);
454 }
455 }
456 }
457
458
rl6548_data_read(void * handle,void * buf,unsigned int size)459 int rl6548_data_read(void *handle, void *buf, unsigned int size)
460 {
461 int sz = size;
462 char *dst = (char*)buf;
463
464 if(sz >= rx_data_cache_len && rx_data_cache_len > 0) {
465 memcpy(dst, rx_data_cache, rx_data_cache_len);
466 sz -= rx_data_cache_len;
467 dst += rx_data_cache_len;
468 rx_data_cache_len = 0;
469 } else if(sz < rx_data_cache_len) {
470 memcpy(dst, rx_data_cache, sz);
471 rx_data_cache_len -= sz;
472 memmove(rx_data_cache, rx_data_cache + sz, rx_data_cache_len);
473 sz = 0;
474 }
475
476 while(sz > 0) {
477 if (sp_get_ready_rx_page()) {
478 sp_read_rx_page((u8 *)rx_data_cache, SP_DMA_PAGE_SIZE);
479 rx_data_cache_len = SP_DMA_PAGE_SIZE;
480 if(sz >= rx_data_cache_len) {
481 memcpy(dst, rx_data_cache, rx_data_cache_len);
482 sz -= rx_data_cache_len;
483 dst += rx_data_cache_len;
484 rx_data_cache_len = 0;
485 } else {
486 memcpy(dst, rx_data_cache, sz);
487 rx_data_cache_len -= sz;
488 memmove(rx_data_cache, rx_data_cache + sz, rx_data_cache_len);
489 sz = 0;
490 }
491 } else {
492 // rtw_msleep_os(1);
493 aos_msleep(1);
494 }
495 }
496 return size - sz;
497 }
498
499
rl6548_volume_set(int index)500 void rl6548_volume_set(int index)
501 {
502 int vol = (int)(VOLUME_MAX / 100.0 * index) ;
503 SET_VOLUME(vol, vol);
504 // printf("Volume Set, index %d, value %d\r\n", index, vol);
505 }
506
507
rl6548_volume_get()508 int rl6548_volume_get()
509 {
510 int vol = 0;
511 int volume_index = 0;
512 u16 volume_16 = 0;
513
514 GET_VOLUME(&volume_16);
515 // printf("Volume Register Data %x", volume_16);
516
517 vol = volume_16 & 0x00FF;
518 volume_index = round(vol * 100.0 / VOLUME_MAX);
519 return volume_index;
520 }
521
522
rl6548_set_mute(int mute)523 void rl6548_set_mute(int mute)
524 {
525 if(mute)
526 rl6548_volume_set(0);
527 }
528
529
rl6548_get_mute()530 int rl6548_get_mute()
531 {
532 return rl6548_volume_get() == 0;
533 }
534