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

📄 audioinit2.c

📁 vxWork RTOS, VOIP example. used in Class 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 "sockLib.h"#include "inetLib.h"#include "stdioLib.h"#include "strLib.h"#include "hostLib.h"#include "taskLib.h"#include "fioLib.h"#include "netinet/tcp.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];char saved_samples[MAX_LINE];static fd_set files;UINT32 * tmp_int;/* 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   256 #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_MY_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 *//*---------------------------------------------------------------------------  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<10000; temp1++) {	taskDelay(10);	/*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 );    writel(ACISV_ISV3 | ACISV_ISV4, CS4281_pBA0 + BA0_ACISV );     /************************************************     *    Unmute the Master and     *    Alternate (headphone) volumes, to max.     ************************************************/    cs4281_write_ac97(BA0_AC97_MASTER_VOLUME, 0x0000);    cs4281_write_ac97(BA0_AC97_HEADPHONE_VOLUME, 0x0000);    cs4281_write_ac97(BA0_AC97_MASTER_VOLUME_MONO, 0x0010);    cs4281_write_ac97(BA0_AC97_PC_BEEP_VOLUME, 0x0010);    cs4281_write_ac97(BA0_AC97_PHONE_VOLUME, 0x0008);    cs4281_write_ac97(BA0_AC97_MIC_VOLUME, 0x0008);    cs4281_write_ac97(BA0_AC97_CD_VOLUME, 0x0808);    cs4281_write_ac97(BA0_AC97_VIDEO_VOLUME, 0x0808);    cs4281_write_ac97(BA0_AC97_AUX_VOLUME, 0x0808);    cs4281_write_ac97(BA0_AC97_PCM_OUT_VOLUME, 0x0000);    cs4281_write_ac97(BA0_AC97_RECORD_GAIN, 0x0b0b);    cs4281_write_ac97(BA0_AC97_RECORD_GAIN_MIC, 0x0b0b);        /************************************************     *    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)	    break;    }     /************************************************     *    POWER on the ADC     ************************************************/    cs4281_read_ac97(BA0_AC97_POWERDOWN, &temp1);    cs4281_write_ac97(BA0_AC97_POWERDOWN, temp1 &= 0xfeff);    /* 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 & 0x1)	    break;    }       /*        For playback, we map AC97 slot 3 and 4(Left        & Right PCM playback) to DMA Channel 0.        Set the fifo to be 15 bytes at offset zero.       */       ac97_slotid = 0x01000f00;          writel(ac97_slotid, CS4281_pBA0 + BA0_FCR0);                        writel(ac97_slotid | FCRn_FEN, CS4281_pBA0 + BA0_FCR0);             /*        For record, we map AC97 slots 3 and 4(Left        & Right Record)	to DMA Channel 1.  Set the 	fifo to be 15 bytes at offset 63.       */       ac97_slotid = 0x0b0a0f3f;          writel(ac97_slotid, CS4281_pBA0 + BA0_FCR1);                        writel(ac97_slotid | FCRn_FEN, CS4281_pBA0 + BA0_FCR1);             /*         Map the Playback SRC to the same AC97 slots(3 & 4--         --Playback left & right)as DMA channel 0.         Map the record SRC to the same AC97 slots(10 & 11--         -- Record left & right) as DMA channel 1.       */       ac97_slotid = 0x0b0a0100;             writel(ac97_slotid, CS4281_pBA0 + BA0_SRCSA);                      /*         Set 'Half Terminal Count Interrupt Enable' and 'Terminal         Count Interrupt Enable' in DMA Control Registers 0 & 1.         Set 'MSK' flag to 1 to keep the DMA engines paused.       *//*       temp1 = (DCRn_TCIE | DCRn_MSK);           writel(temp1, CS4281_pBA0 + BA0_DCR0);          */       temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);           writel(temp1, CS4281_pBA0 + BA0_DCR0);                 temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);           writel(temp1, CS4281_pBA0 + BA0_DCR1);          /*       temp1 = (DCRn_TCIE | DCRn_MSK);           writel(temp1, CS4281_pBA0 + BA0_DCR1);          */       /*         Set 'Auto-Initialize Control' to 'enabled'; For playback,         set 'Transfer Type Control'(TR[1:0]) to 'read transfer',         for record, set Transfer Type Control to 'write transfer'.         All other bits set to zero;  Some will be changed @ transfer start.       */       temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);          writel(temp1, CS4281_pBA0 + BA0_DMR0);                   temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE);          writel(temp1, CS4281_pBA0 + BA0_DMR1);                   /*         Enable DMA interrupts generally, and         DMA0 & DMA1 interrupts specifically.       */       temp1 = readl(CS4281_pBA0 + BA0_HIMR) &  0xfffbfcff;       writel(temp1, CS4281_pBA0+BA0_HIMR);           printf("\nCS4281 Hardware Initialization Complete!!\n");    return 0;}	/*-------------------------  Start DAC / Stop DAC  ------------------------*/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);    writel(0, CS4281_pBA0+BA0_PPRVC);    writel(0, CS4281_pBA0+BA0_PPLVC);        intUnlock(lockkey);}/*-------------------------  Start ADC / Stop ADC  ------------------------*/void start_adc(void){    UINT32 temp1;    int lockkey;        lockkey = intLock();        /* enable Interrupt */    writel(HICR_IEV | HICR_CHGM, CS4281_pBA0+BA0_HICR);    writel(0, CS4281_pBA0+BA0_PPRVC);    writel(0, CS4281_pBA0+BA0_PPLVC);        intUnlock(lockkey);}/*------------------------- set  DMAcntl, SampleRate,

⌨️ 快捷键说明

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