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

📄 wm8510codecdrv.c

📁 dsPIC 录音
💻 C
字号:
#include "..\h\WM8510CodecDrv.h"

WM8510Handle *thisWM8510Codec;

void WM8510Init(WM8510Handle * pHandle, int * pBuffer)
{
	int cleanIt;
	
	DCICON1bits.DCIEN = 0;	/* Disable these modules before configuring them	*/
	I2C1CONbits.I2CEN = 0;
	
	I2C1CONbits.I2CSIDL 	= 0;			/* I2C is running during idle	*/
	I2C1CONbits.IPMIEN 	= 0;			/* IPMI is disabled			*/
	I2C1CONbits.A10M		= 0;			/* 7 bit slave address		*/
	I2C1CONbits.DISSLW 	= 1;			/* No slew control			*/
	I2C1CONbits.SMEN 	= 0;			/* No SMBus Enabled		*/
	
	I2C1BRG = WM8510DRV_I2CBAUD;	/* 100KHz I2C				*/
	WM8510DRV_I2C_TRISSCL = 1;
	WM8510DRV_I2C_TRISSDA = 1;
	
	DCICON1 = WM8510DRV_DCICON1VAL;
	DCICON2 = WM8510DRV_DCICON2VAL;
	TSCON = WM8510DRV_TSCONVAL;
	RSCON = WM8510DRV_RSCONVAL;	
	
	thisWM8510Codec 			= pHandle;
	pHandle->inputBuffer1 		= pBuffer;
	pHandle->inputBuffer2 		= pBuffer + WM8510DRV_CODEC_FRAME ;
	pHandle->outputBuffer1 	= pBuffer + (2*WM8510DRV_CODEC_FRAME );
	pHandle->outputBuffer2 	= pBuffer + (3*WM8510DRV_CODEC_FRAME );
	
	for (cleanIt = 0; cleanIt <  WM8510DRV_DRV_BUFFER_SIZE; cleanIt ++)
		pBuffer[cleanIt] = 0;
	
	
	
}
	
void WM8510Start(WM8510Handle * pHandle)
{
	
	pHandle->statusFlag 			= 0;
	pHandle->statusFlag			|=  WM8510DRV_SET_READ_BUSY;
	pHandle->statusFlag			|=  WM8510DRV_SET_WRITE_BUSY;
	pHandle->activeInputBuffer 		= pHandle->inputBuffer1;
	pHandle->activeOutputBuffer 	= pHandle->outputBuffer1;
	pHandle->currentSampleIndex	= 0;
	pHandle->currentFrameSize 		= WM8510DRV_CODEC_FRAME - 1;
	pHandle->newFrameSize		= WM8510DRV_CODEC_FRAME - 1;
	TXBUF0 						= pHandle->activeOutputBuffer[0] ;
	
	I2C1CONbits.I2CEN 	= 1;			/* Enable the I2C module		*/
	_DCIIF = 0;
	_DCIIE = 1;
	_DCIIP = WM8510DRV_DCI_INTERRUPT_PRIORITY;
	DCICON1bits.DCIEN = 1;			/* Enable the DCI module	*/
}
	
void WM8510Stop(WM8510Handle * pHandle)
{
	
	DCICON1bits.DCIEN = 0;	/* Stop the DCI module	*/
	_DCIIE = 0;				/* Stop Interrupts		*/
}

void WM8510Read(WM8510Handle * pHandle, int * data, int size)
{
	/* The buffer indicator bit in the status register determines which	
	 * which buffer can be read. If flag is 0 then buffer 2 should be read
	 * else buffer should be read. */
	 
	 int * source;
	 int sampleIndex;
	 
	 if((pHandle->statusFlag & WM8510DRV_GET_BUFFER_IND) == 0)
	 {
		 /* This means that buffer 1 is busy and buffer 2 is 
		  * available to read	*/
		source = pHandle->inputBuffer2;
	}
	else
	{
		/* This means that buffer 2 is busy and buffer 1 is 
		  * available to read	*/
		source = pHandle->inputBuffer1;
	}
		  
	if (size > WM8510DRV_CODEC_FRAME)
	{
		size = WM8510DRV_CODEC_FRAME;
	}
		
	for(sampleIndex = 0; sampleIndex < size; sampleIndex++)
	{
		data[sampleIndex] = source[sampleIndex];
	}
	
	/* Set the read busy flag indicating that no buffers are 
	 * available for reading	*/
	 
	__asm__ volatile("disi #0x4"); /* disable interrupts */
	pHandle->statusFlag |= WM8510DRV_SET_READ_BUSY;
	__asm__ volatile("disi #0x0"); /* enable interrupts */
}
	
int WM8510IsWriteBusy(WM8510Handle *pHandle)
{
	return( ((pHandle->statusFlag & WM8510DRV_GET_WRITE_BUSY) == 0) ? 0 : 1); 
}

int  WM8510IsReadBusy(WM8510Handle *pHandle)
{
	return( ((pHandle->statusFlag & WM8510DRV_GET_READ_BUSY) == 0) ? 0 : 1); 
}	

void WM8510Write(WM8510Handle * pHandle, int * data, int size)
{
	/* The buffer indicator bit in the status register determines which	
	 * which buffer can be written to. If flag is 0 then buffer 2 should be 
	 * written to since the driver is writing buffer 1 to the output. */
	 
	 int* destination;
	 int  sampleIndex;
	 
	 if((pHandle->statusFlag & WM8510DRV_GET_BUFFER_IND) == 0)
	 {
		 /* This means that buffer 1 is busy and buffer 2 is 
		  * available to write to	*/
		 destination = pHandle->outputBuffer2;
	}
	else
	{
		/* This means that buffer 2 is busy and buffer 1 is 
		 * available to write to	*/
		destination = pHandle->outputBuffer1;
	}
		  
	if (size > WM8510DRV_CODEC_FRAME)
	{
		size = WM8510DRV_CODEC_FRAME;
	}
	
	/* Update the frame size. The actual switch will happen
	 * in the ISR	*/	
	pHandle->newFrameSize = size;
		
	for(sampleIndex = 0; sampleIndex < size; sampleIndex++)
	{
		destination[sampleIndex] = data[sampleIndex];
	}
	
	/* Set the write busy flag indicating that no buffers are 
	 * available for writing	*/
	__asm__ volatile("disi #0x4"); /* disable interrupts */
	pHandle->statusFlag |= WM8510DRV_SET_WRITE_BUSY;
	__asm__ volatile("disi #0x0"); /* enable interrupts */
}
	
int WM8510IOCtl(WM8510Handle * pHandle,int command, void * value)
{
	/* Use the I2C module to send the control data to the codec
	 * Send the device address first, the upper control word next
	 * which consists of register address and bit B8 of control data
	 * and finally send the control data bits B7-B0	*/
	
	CommandValueWord commandValue;
	
	commandValue.wordValue = *((int *)value);
	commandValue.bytes[1] &= 0x1;
	command = command << 1;
	command = command | commandValue.bytes[1];
	
	
	I2C1CONbits.SEN = 1;					/* Send the start condition 			*/
	while(I2C1CONbits.SEN == 1);			/* Wait for the condition to complete	*/
	
	I2C1TRN = WM8510DRV_I2C_ADDR;			/* Address of the WM8510			*/
	while(I2C1STATbits.TRSTAT);			/* Wait till this has been tranmitted	*/
	if (I2C1STATbits.ACKSTAT)				/* If this value is 1 then a NACK was	*/
	{									/* was recieved					*/
		I2C1CONbits.PEN = 1;
		while(I2C1CONbits.PEN);			/* Send the stop condition if a NACK	*/
		return(-1);						/* was received					*/		
	
	}

	I2C1TRN = command;					/* The address of the register		*/
	while(I2C1STATbits.TRSTAT);			/* Wait till this has been tranmitted	*/
	if (I2C1STATbits.ACKSTAT)				/* If this value is 1 then a NACK was	*/
	{									/* was recieved					*/
		I2C1CONbits.PEN = 1;
		while(I2C1CONbits.PEN);			/* Send the stop condition if a NACK	*/
		return(-1);						/* was received					*/		
	}
	
	I2C1TRN = commandValue.bytes[0];			/* The value of the register			*/
	while(I2C1STATbits.TRSTAT);			/* Wait till this has been tranmitted	*/
	if (I2C1STATbits.ACKSTAT)				/* If this value is 1 then a NACK was	*/
	{									/* was recieved					*/
		I2C1CONbits.PEN = 1;
		while(I2C1CONbits.PEN);			/* Send the stop condition if a NACK	*/
		return(-1);						/* was received					*/		
	}
	
	I2C1CONbits.PEN = 1;
	while(I2C1CONbits.PEN);				/* Send the stop condition			*/
	return(1);
}

void __attribute__((__interrupt__,no_auto_psv)) _DCIInterrupt(void)
{
	_DCIIF = 0;;
	
	/* Send and Recieve Samples */
	
	thisWM8510Codec->activeInputBuffer[thisWM8510Codec->currentSampleIndex] = RXBUF0;
	TXBUF0 = thisWM8510Codec->activeOutputBuffer[thisWM8510Codec->currentSampleIndex];
	thisWM8510Codec->currentSampleIndex++;
	
	if(thisWM8510Codec->currentSampleIndex == thisWM8510Codec->currentFrameSize)
	{
		/* Transmitted one frame of data.
		 * Recieved one frame of data.
		 * Toggle the buffer indicator bit */
	
		thisWM8510Codec->statusFlag ^= WM8510DRV_TGL_BUFFER_IND;
		if((thisWM8510Codec->statusFlag &	WM8510DRV_GET_BUFFER_IND) != 0)
		{
			/* Buffer indicator is 1 means use buffer2	*/
			thisWM8510Codec->activeInputBuffer = thisWM8510Codec->inputBuffer2;
			thisWM8510Codec->activeOutputBuffer = thisWM8510Codec->outputBuffer2;
		}
		else
		{
			/* Buffer indicator is 0 means use buffer1	*/
			thisWM8510Codec->activeInputBuffer = thisWM8510Codec->inputBuffer1;
			thisWM8510Codec->activeOutputBuffer = thisWM8510Codec->outputBuffer1;
		}
		/* Reset the sample index and update the sample count	*/
		thisWM8510Codec->currentSampleIndex = 0;		
		thisWM8510Codec->currentFrameSize = thisWM8510Codec->newFrameSize ;
		thisWM8510Codec->statusFlag &= WM8510DRV_CLR_READ_BUSY;
		thisWM8510Codec->statusFlag &= WM8510DRV_CLR_WRITE_BUSY;
	}
}

void WM8510SampleRate8KConfig(WM8510Handle *codecHandle)
{
	int commandValue,result;
	commandValue = 1;		/* Any value can be written to reset the codec	*/
	result = WM8510IOCtl(codecHandle,WM8510_SOFTWARE_RESET, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b001101111;		
	WM8510IOCtl(codecHandle,WM8510_POWER_MGMT1, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000010101;
	WM8510IOCtl(codecHandle,WM8510_POWER_MGMT2, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b010001001;
	WM8510IOCtl(codecHandle,WM8510_POWER_MGMT3, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000011000;
	WM8510IOCtl(codecHandle,WM8510_AUDIO_INTERFACE, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b110101001;
	WM8510IOCtl(codecHandle,WM8510_CLOCKGEN_CTRL, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000001010;
	WM8510IOCtl(codecHandle,WM8510_ADDITIONAL_CTRL, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000100;
	WM8510IOCtl(codecHandle,WM8510_GPIO_STUFF, 			(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b100001000;
	WM8510IOCtl(codecHandle,WM8510_ADC_CONTROL	, 		(void *) &commandValue);
	if (result == -1) while(1);
		
	commandValue = 0b001000000;
	WM8510IOCtl(codecHandle,WM8510_NOTCH_FILTER1, 		(void *) &commandValue);
	if (result == -1) while(1);
	
	commandValue = 0b000000101;
	WM8510IOCtl(codecHandle,WM8510_NOTCH_FILTER2, 		(void *) &commandValue);
	if (result == -1) while(1);
	
	commandValue = 0b000111111;
	WM8510IOCtl(codecHandle,WM8510_NOTCH_FILTER3, 		(void *) &commandValue);
	if (result == -1) while(1);
	
	commandValue = 0b001111101;
	WM8510IOCtl(codecHandle,WM8510_NOTCH_FILTER4, 		(void *) &commandValue);
	if (result == -1) while(1);
	
	commandValue = 0b100000000;
	WM8510IOCtl(codecHandle,WM8510_NOTCH_FILTER4, 		(void *) &commandValue);
	if (result == -1) while(1);
	
	commandValue = 0b000011000;
	WM8510IOCtl(codecHandle,WM8510_PLL_N, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000001100;
	WM8510IOCtl(codecHandle,WM8510_PLL_K1, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b010010011;
	WM8510IOCtl(codecHandle,WM8510_PLL_K2, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b011101001;
	WM8510IOCtl(codecHandle,WM8510_PLL_K3, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000100;
	WM8510IOCtl(codecHandle,WM8510_INPUT_CTRL, 			(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000000;
	WM8510IOCtl(codecHandle,WM8510_ADC_BOOST_CTRL, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000001;
	WM8510IOCtl(codecHandle,WM8510_MONO_MIXER_CTRL,	 (void *) &commandValue);
	if (result == -1) while(1);

}

void WM8510SampleRate16KConfig(WM8510Handle *codecHandle)
{
	int commandValue,result;
	commandValue = 1;		/* Any value can be written to reset the codec	*/
	result = WM8510IOCtl(codecHandle,WM8510_SOFTWARE_RESET, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b001101111;		
	WM8510IOCtl(codecHandle,WM8510_POWER_MGMT1, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000010101;
	WM8510IOCtl(codecHandle,WM8510_POWER_MGMT2, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b010001001;
	WM8510IOCtl(codecHandle,WM8510_POWER_MGMT3, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000011000;
	WM8510IOCtl(codecHandle,WM8510_AUDIO_INTERFACE, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b101101001;
	WM8510IOCtl(codecHandle,WM8510_CLOCKGEN_CTRL, 		(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000110;
	WM8510IOCtl(codecHandle,WM8510_ADDITIONAL_CTRL, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000100;
	WM8510IOCtl(codecHandle,WM8510_GPIO_STUFF, 			(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000011000;
	WM8510IOCtl(codecHandle,WM8510_PLL_N, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000001100;
	WM8510IOCtl(codecHandle,WM8510_PLL_K1, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b010010011;
	WM8510IOCtl(codecHandle,WM8510_PLL_K2, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b011101001;
	WM8510IOCtl(codecHandle,WM8510_PLL_K3, 				(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000100;
	WM8510IOCtl(codecHandle,WM8510_INPUT_CTRL, 			(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000000;
	WM8510IOCtl(codecHandle,WM8510_ADC_BOOST_CTRL, 	(void *) &commandValue);
	if (result == -1) while(1);
	commandValue = 0b000000001;
	WM8510IOCtl(codecHandle,WM8510_MONO_MIXER_CTRL,	 (void *) &commandValue);
	if (result == -1) while(1);

}

⌨️ 快捷键说明

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