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

📄 audioinit.c

📁 vxWork, VOIP playback function. used in graduate final project.
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************** * CS4281.c   the driver for soundcard cs4281 in VxWorks         * *                                                               * *          U of Colorado at Boulder                             * *****************************************************************//* VxWorks API includes */#include "vxWorks.h"#include "stdio.h"#include "stdlib.h"#include "ioLib.h"#include "semLib.h"#include "intLib.h"#include "iv.h"#include "tcpExample.h"/* VxWorks 5.4 PCI driver interface includes */#include "drv/pci/pciConfigLib.h"#include "drv/pci/pciConfigShow.h"#include "drv/pci/pciHeaderDefs.h"#include "drv/pci/pciLocalBus.h"#include "drv/pci/pciIntLib.h"/* pcPentium BSP includes */#include "sysLib.h"    /* Cystal cs4281 and ac97 hardware */#include "cs4281Registers.h"extern unsigned char pbdata[];char adNauseam[MAX_LINE];/* Local definition of CS4281 values */#define PCI_VENDOR_ID_CIRRUS         0X1013#define PCI_DEVICE_ID_CRYSTAL_CS4281 0X6005#define CS4281_pBA0       0x04000000#define CS4281_pBA1       0x05000000#define INT_NUM_IRQ0      0x20/* Dac and Adc buffers */#define DAC_BUFFER_SIZE   4096#define ADC_BUFFER_SIZE   DAC_BUFFER_SIZEvoid *DAC_BUFFER = NULL;void *ADC_BUFFER = NULL;int PIPE_SNDBUF = ERROR;/* Interrupt Service Related*/unsigned char cs4281_irq;SEM_ID  SEM_DMA_Playback, SEM_DMA_Record; /* semophores */int     CNT_DMA_Playback, CNT_DMA_Record; /* debug counter */int     DTC_DMA_Playback, DTC_DMA_Record; /* Empty or Half Empty */char WAVTBL[1024+128*2048];/*---------------------------------------------------------------------------  Hardware interface For the CS4281  --------------------------------------------------------------------------*//* Read from PCI Address 'offset'  */UINT32 readl(UINT32 offset){    UINT32 result;    PCI_READ(offset, 0x0, &result);    return result;}/* Write value to PCI Address 'offset' */int    writel(UINT32 value, UINT32 offset){    PCI_WRITE(offset,0x0, value);    return 0;}/*************************************************************************** cs4281_read_ac97: read a word from the CS4281 address space (based on BA0)     step-1: write ACCAD (Commond Address Register) 46C h     step-2: write ACCDA (Command Data    Register) 470 h, 0 for read     step-3: write ACCTL (Control         Register) 460 h, initiating op     step-4: read  ACCTL , until DCV is reset and [460h] = 17h     step-5: if DCV not cleared, error     step-6: read  ACSTS (Status          Register) 464 h, check VSTS bit****************************************************************************/int cs4281_read_ac97(UINT32 offset, UINT32 *value){    UINT32 count, status;    /* Make sure there is no data in ACSDA[47Ch] */    status = readl(CS4281_pBA0 + BA0_ACSDA);    /* Get the actual offset, and read ... */    writel( offset - BA0_AC97_RESET, CS4281_pBA0 + BA0_ACCAD );    writel( 0, CS4281_pBA0 + BA0_ACCDA );    writel( ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN,	    CS4281_pBA0 + BA0_ACCTL );    /* Wait fo the read to occur */    for( count = 0; count < 10; count ++ ) {	taskDelay(25);	/*udelay(25);*/	/* check if read is complete */	if(! (readl(CS4281_pBA0 + BA0_ACCTL) & ACCTL_DCV) )	    break;    }    if( readl(CS4281_pBA0 + BA0_ACCTL) & ACCTL_DCV )	return 1;    /* Wait for the valid status bit to go active */    for( count = 0; count < 10; count ++ ) {	status = readl(CS4281_pBA0 + BA0_ACSTS);	if(status & ACSTS_VSTS)	    break;	taskDelay(25);	/*udelay(25);*/    }    if(!(status & ACSTS_VSTS))	return 1;    /* Read data from the AC97 register 474h */    *value = readl( CS4281_pBA0 + BA0_ACSDA );    return 0;}/****************************************************************************  cs4281_wrote_ac97() : write a word to the cs4281 address space      step-1: write ACCAD (Command Address Register) 46C h      step-2: write ACCDA (Command Data    Register) 470 h      step-3: write ACCTL (Control         Register) 460 h      step-4: read  ACCTL,  DCV should be reset and [460h] = 07h      step-5: if DCV not cleared, error*****************************************************************************/int cs4281_write_ac97(UINT32 offset, UINT32 value ){    UINT32 count, status;    /* write to the actual AC97 register */    writel(offset - BA0_AC97_RESET, CS4281_pBA0 + BA0_ACCAD);    writel(value, CS4281_pBA0 + BA0_ACCDA);    writel(ACCTL_DCV | ACCTL_VFRM |ACCTL_ESYN, CS4281_pBA0 + BA0_ACCTL);    /* Wait for write to finish ... */    for(count=0; count<10; count ++) {	taskDelay(25);	/*udelay(25);*/	/* check if write complete */	status = readl(CS4281_pBA0 + BA0_ACCTL);	if(!(status & ACCTL_DCV))	    break;    }    if(status & ACCTL_DCV)	return 1;    return 0;}/*************************************************************************** cs4281_hw_init:   bring up the part**************************************************************************/int cs4281_hw_init( void ){    UINT32 ac97_slotid;    UINT32 temp1, temp2;    /****************************************************     *      set up the Sound System configuration     ****************************************************/    printf("\nCS4281 HardWare Initialization ...\n");    /* ease the 'write protect' */    writel(0x4281, CS4281_pBA0 + BA0_CWPR);    /* Blast the clock control register to 0, so that PLL starts out       Blast the master serial port cntl register to 0, so that serial port       starts out    */    writel(0, CS4281_pBA0 + BA0_CLKCR1);    writel(0, CS4281_pBA0 + BA0_SERMC);    /***** <1> Make ESYN go to 0, to turn off the Sync pulse */    writel(0, CS4281_pBA0 + BA0_ACCTL);    taskDelay(50);    /*udelay(50);*/    /***** <2> Drive ARST# pin low for 1uS, then drive high, so that the	   external logic are reset    */    writel(0, CS4281_pBA0 + BA0_SPMC);    taskDelay(100);    /* udelay(100);*/    writel(SPMC_RSTN, CS4281_pBA0 + BA0_SPMC);    taskDelay(500);    /*delayus(50000);*/    /***** <3> Turn on the Sound System clocks */    writel(CLKCR1_PLLP, CS4281_pBA0 + BA0_CLKCR1);    taskDelay(500);    /*delayus(50000);*/    writel(CLKCR1_PLLP | CLKCR1_SWCE, CS4281_pBA0 + BA0_CLKCR1);    /***** <4> Power on everything for now */    writel(0x7e, CS4281_pBA0 + BA0_SSPM);    /***** <5> Wait for clock stabilization */    for(temp1=0; temp1<1000; temp1++) {	taskDelay(1);	/*udelay(1000);*/	if( readl(CS4281_pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY )	    break;    }    if(!(readl(CS4281_pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)) {	printf("cs4281: DLLRDY failed! \n");	return -1;    }    /***** <6> Enable ASYNC generation */    writel(ACCTL_ESYN, CS4281_pBA0 +BA0_ACCTL);    /* wait for a while to start generating bit clock */    taskDelay(500);    /*dealyus(50000);*/    /* Set the serial port timing configuration */    writel( SERMC_PTC_AC97, CS4281_pBA0 + BA0_SERMC );    /***** <7> Wait for the codec ready signal from the AC97 codec */    for(temp1=0; temp1<1000; temp1++) {	taskDelay(1);	/*udelay(1000);*/	if(readl(CS4281_pBA0 + BA0_ACSTS) & ACSTS_CRDY )	    break;    }    if(!(readl(CS4281_pBA0 + BA0_ACSTS)& ACSTS_CRDY)) {	printf("cs4281: ACTST never came ready!\n");	return -1;    }    /***** <8> Assert the 'valid frame' signal to begin sending	   commands to AC97 codec */    writel(ACCTL_VFRM |ACCTL_ESYN, CS4281_pBA0 + BA0_ACCTL);    /***** <9> Wait until CODEC calibration is finished.*/    for(temp1=0; temp1<1000; temp1++) {	taskDelay(10);	/*	delayus(10000);*/	if(cs4281_read_ac97(BA0_AC97_POWERDOWN, &temp2) )	  return -1;	if( (temp2 & 0x0000000F) == 0x0000000F )	    break;    }    if( (temp2 & 0x0000000F) != 0x0000000F ) {	printf("cs4281: Codec failed to calibrate\n");	return -1;    }    /***** <12> Start digital data transfer of audio data to codec */    writel(ACOSV_SLV3 | ACOSV_SLV4, CS4281_pBA0 + BA0_ACOSV );    /************************************************     *    Unmute the Master and     *    Alternate (headphone) volumes, to max.     ************************************************/    cs4281_write_ac97(BA0_AC97_HEADPHONE_VOLUME, 0);    cs4281_write_ac97(BA0_AC97_MASTER_VOLUME, 0);    cs4281_write_ac97(BA0_AC97_MASTER_VOLUME_MONO, 0);    cs4281_write_ac97(BA0_AC97_PC_BEEP_VOLUME, 0);    cs4281_write_ac97(BA0_AC97_PHONE_VOLUME, 0);     cs4281_write_ac97(BA0_AC97_CD_VOLUME, 0);    cs4281_write_ac97(BA0_AC97_VIDEO_VOLUME, 0);    cs4281_write_ac97(BA0_AC97_AUX_VOLUME, 0);      cs4281_write_ac97(BA0_AC97_PCM_OUT_VOLUME, 0);    cs4281_write_ac97(BA0_AC97_MASTER_VOLUME, 0);    cs4281_write_ac97(BA0_AC97_HEADPHONE_VOLUME, 0);        /************************************************     *    POWER on the DAC     ************************************************/    cs4281_read_ac97(BA0_AC97_POWERDOWN, &temp1);    cs4281_write_ac97(BA0_AC97_POWERDOWN, temp1 &= 0xfdff);    /* Wait until we sample a DAC ready state */    for(temp2=0; temp2<32; temp2++) {	taskDelay(1);	/*	delayus(1000);*/	cs4281_read_ac97(BA0_AC97_POWERDOWN, &temp1);	if(temp1 & 0x2)

⌨️ 快捷键说明

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