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

📄 i2s_jz4740.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************** BEGIN LICENSE BLOCK ************************************ * * JZ4740  mobile_tv  Project  V1.0.0 * INGENIC CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM * Copyright (c) Ingenic Semiconductor Co. Ltd 2005. All rights reserved. *  * This file, and the files included with this file, is distributed and made  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.  *  * http://www.ingenic.cn  * ********************** END LICENSE BLOCK ************************************** * *  Author:  <dsqiu@ingenic.cn>  <jgao@ingenic.cn>  * *  Create:   2008-06-26, by dsqiu *             *  Maintain: 2008-06-26, by jgao *             * ******************************************************************************* */#include <includes.h>#include <jz4740.h>#include "pcm.h"#include "dm.h"#include "i2s_codec_jz4740.h"#define CONFIG_I2S_AK4642EN#define DMAC_DCCSR_DAM DMAC_DCMD_DAI#define DMAC_DCCSR_SAM DMAC_DCMD_SAI#define DMAC_DCCSR_RDIL_IGN DMAC_DCMD_RDIL_IGN#ifndef u8#define u8 unsigned char#endif#ifndef u16#define u16 unsigned short#endif#ifndef u32#define u32 unsigned int#endif#define AUDIO_READ_DMA	2#define AUDIO_WRITE_DMA	3#ifdef PHYADDR#undef PHYADDR#endif#define PHYADDR(n)	((n) & 0x1fffffff)#ifdef KSEG1ADDR#undef KSEG1ADDR#endif#define	KSEG1ADDR(n)	(PHYADDR(n) | 0xa0000000)#ifdef PAGE_SIZE#undef PAGE_SIZE#endif#define QUEUE_MAX 0x4#define PAGE_SIZE	(0x10000 / QUEUE_MAX)extern void HP_turn_off(void);#define STANDARD_SPEED  48000#define SYNC_CLK	48000#define MAX_RETRY       100extern int HP_on_off_flag;static unsigned long i2s_clk;static int		jz_audio_b; static int		jz_audio_rate;static char		jz_audio_format;static char		jz_audio_channels;static char		jz_audio_volume;static u16		jz_audio_factor;int codec_get_rate(void) {return jz_audio_rate;}char codec_get_format(void) {return jz_audio_format;}char codec_get_channels(void) {return jz_audio_channels;}static void jz_update_filler(int bits, int channels);static void jz_i2s_replay_dma_irq(unsigned int);static void jz_i2s_record_dma_irq(unsigned int);static void (*replay_filler)(unsigned long src_start, int count, int id);static int (*record_filler)(unsigned long dst_start, int count, int id);static long old_mute=0;  static long new_mute=0;  static long old_hw_vol=0;  static long new_hw_vol=0;  static int flag_CDCCR=0;  static int	pause_flag=0;/*start*****************add volum control -by gaojian***********************/#if 0static void get_factor(int level);static void fill_sample_table(void);static u16 get_new_sample(int sample);static int              codec_volue_factor;static int              codec_volue_hpmute;static int              codec_volue_hpvol;static u16 sample_table[32768];static u16 get_new_sample(int sample){	printf("sample:%d",sample);	if (sample >= 0)		return sample_table[sample];	else		return (-(sample_table[(-sample)] + 1));}static void fill_sample_table(void){	int cnt;      	sample_table[0] = 0;	for (cnt = 1; cnt <= 32767; cnt++)		//sample_table[cnt] = (u16)((cnt * codec_volue_factor) >> 8);		sample_table[cnt] = (u16)(cnt * codec_volue_factor / 30);}static void get_factor(int level){	int hpmute = 0, hpvol = 0, factor = 0;	switch (level) {	case 1 ... 30:		hpmute = 0;		hpvol = 0;		factor = level;		break;	case 0:		hpmute = 1;		hpvol = 0;		factor = 0;		break;	}	codec_volue_factor = factor;	codec_volue_hpvol = hpvol;	codec_volue_hpmute = hpmute;}#endif/*end*****************add volum control -by gaojian ***********************/#if 0static u16 Factor_table[32] = {	0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240,256,	   216, 230, 243, 256, 214,224, 235, 245, 256, 212, 221, 230, 238, 247,256};#endifstatic u16 Factor_table[32] = {	0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225,256,	   216, 230, 243, 256, 214,224, 235, 245, 256, 212, 221, 230, 238, 247,256};////////////////////////////////////////typedef struct buffer_queue_s {	int count;	int id[QUEUE_MAX];	int oldid;} buffer_queue_t;#if 0typedef struct left_right_sample_s{	signed short left;	signed short right;} left_right_sample_t;#endif//static left_right_sample_t save_last_samples[64];static unsigned long out_dma_buf[QUEUE_MAX+1];static unsigned long out_dma_pbuf[QUEUE_MAX+1];static unsigned long out_dma_buf_data_count[QUEUE_MAX+1];static unsigned long in_dma_buf[QUEUE_MAX+1];static unsigned long in_dma_pbuf[QUEUE_MAX+1];static unsigned long in_dma_buf_data_count[QUEUE_MAX+1];static buffer_queue_t out_empty_queue;static buffer_queue_t out_full_queue;static buffer_queue_t out_busy_queue;static buffer_queue_t in_empty_queue;static buffer_queue_t in_full_queue;static buffer_queue_t in_busy_queue;static int first_record_call = 0;static OS_EVENT *tx_sem;static OS_EVENT *rx_sem;//static OS_EVENT *pause_sem;//static OS_EVENT *pre_tx_sem;static int preconvert_control = 0;static int IS_WRITE_PCM;#define CODE_RESET_BUFSIZE (256)#define CODE_RESET_THREAD_PRIO 130 #define CODE_POWER_ON  0#define CODE_POWER_OFF 1static OS_STK code_reset_buf[CODE_RESET_BUFSIZE];static volatile int code_power = 0; //power on statestatic unsigned int save_REG_ICDC_CDCCR1,save_REG_ICDC_CDCCR2;static int power_count = 1;static  OS_EVENT  *jz_codepower_sem = NULL;#define OP_CODEPOWER_LOCK() do{ \					unsigned char  err; \					OSSemPend(jz_codepower_sem, 0, &err); \					}while(0) #define OP_CODEPOWER_UNLOCK() do{ \							unsigned char  err; \							OSSemPost(jz_codepower_sem); \							}while(0)#define WAIT_POWERON() while(code_power) OSTimeDly(10)							void  jz_codec_poweron(int d);void  jz_codec_poweroff(int d);static inline int get_buffer_id(struct buffer_queue_s *q){	int r;	unsigned long flags;	int i;	if (q->count == 0)		return -1;	flags = spin_lock_irqsave();		r = q->id[0];	for (i=0;i < q->count-1;i++)		q->id[i] = q->id[i+1];	q->count --;	spin_unlock_irqrestore(flags);	return r;}static inline void put_buffer_id(struct buffer_queue_s *q, int id){	unsigned long flags;	flags = spin_lock_irqsave();	q->id[q->count] = id;	q->count ++;	spin_unlock_irqrestore(flags);}static  inline int elements_in_queue(struct buffer_queue_s *q){	int r;	unsigned long flags;	flags=spin_lock_irqsave();	r = q->count;	spin_unlock_irqrestore(flags);	return r;}/**************************************************************************** * Architecture related routines ****************************************************************************/static void jz_i2s_record_dma_irq (unsigned int arg){	int dma = AUDIO_READ_DMA;	int id1, id2;	dma_stop(dma);//	if(preconvert_control==1)//	{//		OSSemPost(pre_tx_sem);//		return;//	}	if (__dmac_channel_address_error_detected(dma)) {		printf("%s: DMAC address error.\n", __FUNCTION__);		__dmac_channel_clear_address_error(dma);	}	if (__dmac_channel_transmit_end_detected(dma)) {		__dmac_channel_clear_transmit_end(dma);		id1 = get_buffer_id(&in_busy_queue);		put_buffer_id(&in_full_queue, id1);		//__dcache_invalidate_all();		OSSemPost(rx_sem);		if ((id2 = get_buffer_id(&in_empty_queue)) >= 0) {			put_buffer_id(&in_busy_queue, id2);			in_dma_buf_data_count[id2] = in_dma_buf_data_count[id1];			dma_start(dma, PHYADDR(AIC_DR), in_dma_pbuf[id2],				  in_dma_buf_data_count[id2]);		} else			in_busy_queue.count = 0;	}}#if 0int pause_flag,control=0,jz_pause_flag =0,restart=0;int restart_count = 1;static int restart_pcm(unsigned int smp,unsigned char *p){	signed short l_sample,r_sample;	signed char *mono;	unsigned int cur_dma_buffer_count = 0;	int i,l_flag,r_flag,step_len;	signed int left_sam,right_sam,temp,l_val,r_val;	unsigned long l_sample_count,r_sample_count,sample_count,temp_convert;	volatile signed short *stero;	volatile signed short value;	//smp  =  smp - jz_audio_channels * 1;		switch(jz_audio_b)	{	case 8:		mono = (signed char *)p;		break;			case 16:		stero = (signed short *)p;		break;	}			switch(jz_audio_channels)	{	case 1:		l_sample = (unsigned int)mono[smp];		r_sample = (unsigned int)mono[smp + 1];		break;			case 2:		l_sample = (signed short)( *(stero) );		r_sample = (signed short)( *(stero + 1) );		//printf("\n{ l_sample:%d ; r_sample:%d }",l_sample,r_sample);		left_sam = (signed int)l_sample;		right_sam = (signed int)r_sample;		sample_count = smp / 4;                ////////////////////////////////////////		for(i=0;i <= (sample_count/2);i++) {			/*if(sample_count/2 > 20) {				if((i < 10) || (i > (sample_count/2 - 10) ))					printf("A[ %d : %d---%d ]\n",i,(signed int)(*(stero + i)),(signed int)(*(stero + sample_count - i)));					}*/			l_val = (signed int)(*(stero + i));			*(stero + i) = *(stero + sample_count - i);			*(stero + sample_count - i) = (signed short)l_val;					/*if(sample_count/2 > 20) {				if((i < 10) || (i > (sample_count/2 - 10) ))					printf("B[ %d : %d---%d ]\n",i,(signed int)(*(stero + i)),(signed int)(*(stero + sample_count - i)));					}*/		}		cur_dma_buffer_count = smp;                ////////////////////////////////////////////		break;	}	 	return cur_dma_buffer_count;}static int insert_pcm(unsigned int smp,unsigned char *p){	signed short l_sample,r_sample;	signed char *mono;	unsigned int cur_dma_buffer_count = 0;	int i,l_flag,r_flag,step_len;	signed int left_sam,right_sam,temp,l_val,r_val;	unsigned long l_sample_count,r_sample_count,sample_count,temp_convert;	volatile signed short *stero;	volatile signed short value;	//smp  =  smp - jz_audio_channels * 1;	if(smp == 0) return 0;	switch(jz_audio_b)	{	case 8:		mono = (signed char *)p;		break;			case 16:		stero = (signed short *)p;		break;			}		switch(jz_audio_channels)	{	case 1:		l_sample = (unsigned int)mono[smp];		r_sample = (unsigned int)mono[smp + 1];		break;			case 2:		l_sample = (signed short)( *(stero + (smp/2) -2) );		r_sample = (signed short)( *(stero + (smp/2) -1) );		left_sam = (signed int)l_sample;		right_sam = (signed int)r_sample;		if(left_sam == 0 && right_sam == 0)			return 0;		//insert some sample here                ////////////////////////////////////////		memset(p,0,smp);		step_len = jz_audio_rate / 10 * 4;		step_len /= 2;		step_len = 0x7fff / step_len + 1;		l_sample_count = 0;		l_val = left_sam;		while(1) {			if(l_val > 0) {				if(l_val >= step_len) {					l_val -= step_len;					l_sample_count ++;				} else					break;			} 						if(l_val < 0) {				if(l_val <= -step_len) {					l_val += step_len;					l_sample_count ++;				} else					break;			}						if(l_val == 0) 				break;		}		r_sample_count = 0;		r_val = right_sam;		while(1) {			if(r_val > 0) {				if(r_val >= step_len) {					r_val -= step_len;					r_sample_count ++;				} else					break;			} 						if(r_val < 0) {				if(r_val <= -step_len) {					r_val += step_len;					r_sample_count ++;				} else					break;			}						if(r_val == 0)				break;					}		//fill up		if(l_sample_count > r_sample_count)			sample_count = l_sample_count;		else			sample_count = r_sample_count;		l_val = left_sam;		r_val = right_sam;		for(i=0;i <= sample_count;i++) {						*stero = (signed short)l_val;						stero ++;						if(l_val > step_len) {				l_val -= step_len;			} else if(l_val < -step_len) {				l_val += step_len;			} else if(l_val >= -step_len && l_val <= step_len) {				l_val = 0;			}			*stero = (signed short)r_val;			stero ++;			if(r_val > step_len) {				r_val -= step_len;			} else if(r_val < -step_len) {				r_val += step_len;			} else if(r_val >= -step_len && r_val <= step_len) {				r_val = 0;			}		}				*stero = 0;			stero ++;		*stero = 0;			stero ++;		sample_count += 1;			*stero = 0;			stero ++;		*stero = 0;			stero ++;		sample_count += 1;		*stero = 0;			stero ++;		*stero = 0;			stero ++;		sample_count += 1;		cur_dma_buffer_count = sample_count * 4;		break;	}	 	return cur_dma_buffer_count;}static void pcm_pause(){	unsigned char err;	int dma = AUDIO_WRITE_DMA;	int id;	if(control==1)	{		control = 0;			}else	{		control = 1;	}			if(pause_flag == 0)	{		pause_flag = 1;		printf("pause:%d\n",pause_flag);	}else	{		pause_flag = 0;		printf("pause:%d\n",pause_flag);		__intc_unmask_irq(20);		id = out_busy_queue.oldid;		if(out_dma_buf_data_count[id] != 0) {			dma_start(dma, out_dma_pbuf[id], PHYADDR(AIC_DR),					  out_dma_buf_data_count[id]);		}			}}static void pcm_start(void){	unsigned char err;	int dma = AUDIO_WRITE_DMA;	int id;	__intc_unmask_irq(20);	id = out_busy_queue.oldid;	if(out_dma_buf_data_count[id] != 0) {		dma_start(dma, out_dma_pbuf[id], PHYADDR(AIC_DR),			  out_dma_buf_data_count[id]);	}	}#endif #if 1static inline  void set_hw_volume(void){	//set CDCCR1	if(flag_CDCCR)	{		if(old_mute!=new_mute)		{			i2s_codec_set_mute(new_mute);		old_mute=new_mute;		}		if(old_hw_vol!=new_hw_vol)		{			i2s_codec_set_volume(new_hw_vol);			old_hw_vol=new_hw_vol;		}		flag_CDCCR=0;	}}static void jz_i2s_replay_dma_irq (unsigned int arg){	int dma = AUDIO_WRITE_DMA;	int id;	dma_stop(dma);	if (__dmac_channel_address_error_detected(dma)) {		printf("%s: DMAC address error.\n", __FUNCTION__);		__dmac_channel_clear_address_error(dma);	}	if (__dmac_channel_transmit_end_detected(dma)) {		__dmac_channel_clear_transmit_end(dma);				if ((id = get_buffer_id(&out_busy_queue)) < 0)			printf("Strange DMA finish interrupt for AIC module\n");                                //set hardware volume		set_hw_volume();		put_buffer_id(&out_empty_queue, id);		if ((id = get_buffer_id(&out_full_queue)) >= 0) {			put_buffer_id(&out_busy_queue, id);			dma_start(dma, out_dma_pbuf[id], PHYADDR(AIC_DR),				  out_dma_buf_data_count[id]);		} else			out_busy_queue.count = 0;		//	if (elements_in_queue(&out_empty_queue) > 0)		//	OSSemPost(tx_sem);	}}#endif#if 0void anti_pop_1(void){	unsigned char err;	int dma = AUDIO_WRITE_DMA;	int id;	int i,j,tx_con=0,step_cnt,step_len;	int d;	unsigned short left,right,tmp1,tmp2;

⌨️ 快捷键说明

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