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

📄 audioinit.c

📁 基于实时嵌入式系统的voip系统(real time embeded system)。主要难点在实时处理语音信号。语音信号基于其自身特点
💻 C
📖 第 1 页 / 共 2 页
字号:
	*/	temp1 = readl(CS4281_pBA0 + BA0_HIMR) &  0xfffbfcff;	writel(temp1, CS4281_pBA0+BA0_HIMR);	printf("\nCS4281 Hardware Initialization Complete!!\n");	return 0;}/***************************************************************************   Function - start_dac*   Parameters - none*   Returns - none*   Purpose - Start DAC and ADC.*     Enables DMA0 an DMA1, Enables Interrupt, sets volume to 0 db.*****************************************************************************/void start_dac(void){	UINT32 temp1;	int lockkey;	lockkey = intLock();	/* enable DMA0 */	temp1 = readl(CS4281_pBA0+BA0_DCR0);	writel(temp1 & ~DCRn_MSK, CS4281_pBA0+BA0_DCR0);	/* enable DMA1*/	temp1 = readl(CS4281_pBA0+BA0_DCR1);	writel(temp1 & ~DCRn_MSK, CS4281_pBA0+BA0_DCR1);	/* enable Interrupt */	writel(HICR_IEV | HICR_CHGM, CS4281_pBA0+BA0_HICR);	/* set volume to 0 db */	writel(0, CS4281_pBA0+BA0_PPRVC);	writel(0, CS4281_pBA0+BA0_PPLVC);	intUnlock(lockkey);}/***************************************************************************   Function - stop_dac*   Parameters - none*   Returns - none*   Purpose - Stops DAC and ADC.*     Disables DMA0 and DMA1, disables interrupt*****************************************************************************/void stop_dac(void){    UINT32 temp1;    int lockkey;    lockkey = intLock();    /* disable DMA0 */    temp1 = readl(CS4281_pBA0+BA0_DCR0);    writel(temp1 | DCRn_MSK, CS4281_pBA0+BA0_DCR0);    /* disable DMA1*/    temp1 = readl(CS4281_pBA0+BA0_DCR1);    writel(temp1 | DCRn_MSK, CS4281_pBA0+BA0_DCR1);    /* disable Interrupt */    writel(HICR_CHGM, CS4281_pBA0+BA0_HICR);    intUnlock(lockkey);}/***************************************************************************   Function - prog_codec*   Parameters - none*   Returns - none*   Purpose - Programs the codec according to the current_mode global*     variable.  Note that DMA should be stopped before changing*     the codec.  It also sets the sample rate to 11025.*****************************************************************************/int prog_codec(void){	UINT32 format,temp1;	int lockkey;	lockkey = intLock();   /*stop the DMAs if active*/	temp1 = readl( CS4281_pBA0+BA0_DCR0);	writel(temp1 | DCRn_MSK, CS4281_pBA0+BA0_DCR0);   /* Stop play DMA, if active.*/	temp1 = readl( CS4281_pBA0+BA0_DCR1);	writel(temp1 | DCRn_MSK, CS4281_pBA0+BA0_DCR1);   /* Stop capture DMA, if active.*/	/* DAC */	/* if 8-bit mono, then set size to 8 and set mono bit */	if( current_mode == 1 )	{		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ | DMRn_USIGN | DMRn_SIZE8 | DMRn_MONO;	}	if( current_mode == 2 ) /*for 8-bit stero set size 8, but not mono*/	{		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ  |DMRn_USIGN | DMRn_SIZE8;	}	if( current_mode == 3 ) /*for 16 bit stereo don't set size 8 or mono*/	{		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ | DMRn_USIGN;	}	writel(format, CS4281_pBA0+BA0_DMR0);	/* ADC*/	/* if 8-bit mono, then set size to 8 and set mono bit */	if( current_mode == 1 )	{		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE | DMRn_USIGN  | DMRn_SIZE8 | DMRn_MONO;	}	if( current_mode == 2 ) /*for 8-bit stero set size 8, but not mono*/	{		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE | DMRn_USIGN | DMRn_SIZE8;	}	if( current_mode == 3 ) /*for 16 bit stereo don't set size 8 or mono*/	{		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE | DMRn_USIGN;	}	if( current_mode == 4 ) /*for 20 bit stereo set size 20 and not mono*/	{		format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE | DMRn_USIGN | DMRn_SIZE20;	}	writel(format, CS4281_pBA0+BA0_DMR1);	/*ADC,DAC set record sampling rate to 11025*/	writel(0x04, CS4281_pBA0+BA0_DACSR);	writel(0x04, CS4281_pBA0+BA0_ADCSR);	intUnlock(lockkey);	return 0;}/***************************************************************************   Function - cs4281_interrupt*   Parameters - param*   Returns - none*   Purpose - Interrupt handler routing.  If TC of HTC interrupt for*     either DMA, then set variable indicating which one and do a*     semGive for either record or play.*****************************************************************************/void cs4281_interrupt(int param){	UINT32 temp1;	int lockkey;	/* if it's not DMA interrupts, jump out */	temp1 = readl(CS4281_pBA0+BA0_HISR);	if(!(temp1 &(HISR_DMA0 | HISR_DMA1)))	{		writel(HICR_IEV| HICR_CHGM, CS4281_pBA0+BA0_HICR);		return;	}	/* if DMA0 interrupt, playback DMA0 */	if(temp1 & HISR_DMA0)	{		CNT_DMA_Playback++;		if(0x00010000 &	readl(CS4281_pBA0+BA0_HDSR0))		{			/*DMA Terminal Count interrupt, set flag saying that */			DTC_DMA_Playback = 1;		}		else /*HTC interrupt, set flag saying that*/		{			DTC_DMA_Playback = 0;		}		semGive(SEM_DMA_Playback);	}	/* if DMA1 interrupt, record DMA1 */	if(temp1 & HISR_DMA1)	{		CNT_DMA_Record++;		if(0x00010000 &	readl(CS4281_pBA0+BA0_HDSR1))		{			/*DMA Terminal Count interrupt, set flag saying that */			DTC_DMA_Record = 1;		}		else /*HTC interrupt, set flag saying that*/		{			DTC_DMA_Record = 0;		}		semGive(SEM_DMA_Record);	}	/*clear interrupt*/	writel(HICR_IEV| HICR_CHGM, CS4281_pBA0+BA0_HICR);}/***************************************************************************   Function - startCS4281*   Parameters - none*   Returns - none*   Purpose - Install the cs4281/ac97 driver:*           -bring up the hardware*           -allocate and set DMA buffer/DMA engine*           -connect ISR to IRQ*           -start_adc/dac*****************************************************************************/int startCS4281(){	unsigned int pciBusNo, pciDevNo, pciFuncNo;	unsigned char byte;	UINT32 s_pBA0, s_pBA1;	if (pciConfigLibInit (PCI_MECHANISM_1, 0xCF8, 0xCFC, 0) != OK)	{		printf("PCI lib config error\n");		return 1;	}	/****************************	* Find SoundCard	* Set  BaseAddr0, BaseAddr1	****************************/	if(!(pciFindDevice(PCI_VENDOR_ID_CIRRUS,PCI_DEVICE_ID_CRYSTAL_CS4281,			 0, &pciBusNo, &pciDevNo, &pciFuncNo)==OK))	{		printf("\n CS4281 sound card NOT FOUND!!! \n");		return 1;	}	printf("\n FIND CS4281 sound card, configuring BA0,BA1... \n");	pciConfigOutLong( pciBusNo, pciDevNo, pciFuncNo,						   PCI_CFG_BASE_ADDRESS_0, CS4281_pBA0);	pciConfigInLong( pciBusNo, pciDevNo, pciFuncNo,						  PCI_CFG_BASE_ADDRESS_0, &s_pBA0);	pciConfigInLong( pciBusNo, pciDevNo, pciFuncNo,						  PCI_CFG_BASE_ADDRESS_1, &s_pBA1 );	printf ("\npBusNo    pDeviceNo  pFuncNo  pBA0      pBA1\n\n");	printf ("%.8x  %.8x  %.8x  %.8x  %.8x \n",	pciBusNo, pciDevNo, pciFuncNo, s_pBA0,s_pBA1);	/********************************	* Config PCI Device Capability	*     DMA Master	*     MEM mapped	********************************/	/* Set the INTA vector */	pciConfigInByte(pciBusNo, pciDevNo, pciFuncNo,						 PCI_CFG_DEV_INT_LINE, &cs4281_irq);	printf("\nFound CS4281 configured for IRQ %d\n", cs4281_irq);	pciConfigInByte(pciBusNo, pciDevNo, pciFuncNo,						 PCI_CFG_DEV_INT_PIN, &byte);	printf("\tINT_PIN=%.8x\n", byte);	/* Enable the device's capabilities as specified	* Bus Master Enable/ Mem Space Enable */	pciConfigOutWord(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_COMMAND,						  (unsigned short)0x0006);	/***************************	* BringUp Hardware	***************************/	if(cs4281_hw_init())		return 1;	/****************************	* Allocate ADC_BUFFER	* Allocate DAC_BUFFER	*	* Hook cs4281_interrupt	*	* Program CoDec	****************************/	if((DAC_BUFFER=valloc(DAC_BUFFER_SIZE))==NULL)	{		printf("\n DAC_BUFFER valloc failed!\n");		return 1;	}	if((ADC_BUFFER=valloc(ADC_BUFFER_SIZE))==NULL)	{		printf("\n ADC_BUFFER valloc failed!\n");		return 1;	}   /*setup DMA BUFFERs for ADC and DAC according to current_mode*/	program_dac_buffers();	/* connect interrupt */	printf("\n Hook cs4281_interrupt to vector %d\n",			 (INUM_TO_IVEC (cs4281_irq+INT_NUM_IRQ0)));	pciIntConnect((INUM_TO_IVEC (cs4281_irq+INT_NUM_IRQ0)),					  (VOIDFUNCPTR)cs4281_interrupt, 0);	sysIntEnablePIC(cs4281_irq);	SEM_DMA_Playback = semBCreate(SEM_Q_FIFO,SEM_EMPTY);	SEM_DMA_Record = semBCreate(SEM_Q_FIFO,SEM_EMPTY);	CNT_DMA_Playback = CNT_DMA_Record = 0;	/* program coDec */	printf("\n Program CoDec (sample rate, DMA...)\n");	prog_codec();	/*********************************************	*  start dac and adc, interrupt is comming...	*********************************************/	printf("\n\n>>>Start DAC !!!!!!!!!!\n");	start_dac();	return 0;}/***************************************************************************   Function - program_dac_buffers*   Parameters - none*   Returns - none*   Purpose - Setup the pointer into and size of buffers.*****************************************************************************/int program_dac_buffers(){    /*tell DMA engine where start of DAC Buffer is*/    /*this had an offset of (-16) which is not needed*/    writel((UINT32)DAC_BUFFER,CS4281_pBA0 + BA0_DBA0);    /*now set the number of FIFO-to-DMA transfers -- this basically    corresponds to size, and it will be different depending on the    mode because the higher modes transfer more data each time, so    it requires fewer transfers to fill the DMA buffer, furthermore    we set the number to one less because we get an interrupt when    rolling over as well*/    if( current_mode == 1 ) /*8 bit mono*/    {       writel(DAC_BUFFER_SIZE-1, CS4281_pBA0 + BA0_DBC0);    }    if( current_mode == 2 ) /*8 bit stereo*/    {       writel((DAC_BUFFER_SIZE/2)-1, CS4281_pBA0 + BA0_DBC0);    }    if( current_mode == 3 ) /*16 bit stereo*/    {       writel((DAC_BUFFER_SIZE/4)-1, CS4281_pBA0 + BA0_DBC0);    }    /*tell DMA engine where start of ADC Buffer is*/    /*this had an offset of (-16) which is not needed*/    writel((UINT32)ADC_BUFFER,CS4281_pBA0 + BA0_DBA1);    /*set # transfers for ADC*/    if( current_mode == 1 ) /*8 bit mono*/    {       writel(ADC_BUFFER_SIZE-1, CS4281_pBA0 + BA0_DBC1);    }    if( current_mode == 2 ) /*8 bit stereo*/    {       writel((ADC_BUFFER_SIZE/2)-1, CS4281_pBA0 + BA0_DBC1);    }    if( current_mode == 3 ) /*16 bit stereo*/    {       writel((ADC_BUFFER_SIZE/4)-1, CS4281_pBA0 + BA0_DBC1);    }}/***************************************************************************   Function - audio_switchMode*   Parameters - none*   Returns - none*   Purpose - This re-configures the codec and DMA buffers to a new mode,*             it assumes new mode has already been set via the global*             current_mode variable.*****************************************************************************/int audio_switchMode(){   prog_codec();   program_dac_buffers();   start_dac();   return 0;}

⌨️ 快捷键说明

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