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

📄 ac97_example.c

📁 含t h r e a d x,u c o s 的b s p
💻 C
字号:
/***********************************************************************
 * $Workfile:   ac97_example.c  $
 * $Revision:   1.0  $
 * $Author:   WellsK  $
 * $Date:   Dec 05 2003 08:56:16  $
 *
 * Project: AC97 DMA mode driver example
 *
 * Description:
 *     A AC97 driver (DMA record) example.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/bsps/sdk7a404/examples/ac97_dma_record/ac97_example.c-arc  $
 * 
 *    Rev 1.0   Dec 05 2003 08:56:16   WellsK
 * Initial revision.
 * 
 *
 ***********************************************************************
 * SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
 * OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
 * AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 * SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
 *
 * SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 * FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 * SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
 * FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
 *
 * COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/

#include "abl_types.h"
#include "abl_irq_fiq.h"
#include "abl_arm922t_cp15_driver.h"
#include "lh7a404_ac97_driver.h"
#include "lh7a404_timer_driver.h"
#include "lh7a404_vic_driver.h"
#include "lh7a404_csc_driver.h"
#include "lh7a404_dma_driver.h"
#include "sdk7a404_cpld_driver.h"

/* Number of samples to record */
#define REC_SAMPLES 70000

/* Array of samples */
UNS_8 sound_data[REC_SAMPLES];

/***********************************************************************
 *
 * Function: c_entry
 *
 * Purpose: DMA mode AC97 driver (record) example
 *
 * Processing:
 *     See function. This example sets up the CODEC to record a stereo
 *     sample on the line in input and play it back on the PCM stereo
 *     output.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Always returns 1
 *
 * Notes: None
 *
 **********************************************************************/
int c_entry(void)
{
    INT_32 xa, ac97dev1, loop;
    AC97_VOLUME_T vol;
    AC97_MIX_GAIN_T mix;
    AC97_TONE_T tone;
    AC97_CHANNEL_CONFIG_T chcfg;
    AC97_REC_GAIN_T recgain;
    DMAC_CHANNEL_T dmach;
    UNS_32 *phyaddr;
    VIC_INT_SOURCE_T vici;

    /* Disable interrupts */
    disable_irq_fiq();

    /* Set virtual address of MMU table (needed for VIC driver
       functions) */
    cp15_set_vmmu_addr((UNS_32 *) cp15_get_ttb());

    /* Initialize CPLD */
    cpld_init();

    /* Initialize interrupt system */
    vic_initialize(0xC0000000);

    /* Install standard IRQ dispatcher at ARM IRQ vector */
    vic_install_arm_handler(IRQ_VEC, (PFV) vic_arm_irq_dispatcher);

    /* Install VIC1 and VIC2 handlers */
    vic_install_arm_handler(VIC1_IRQ_VEC, (PFV) vic1_irq_dispatcher);
    vic_install_arm_handler(VIC2_IRQ_VEC, (PFV) vic2_irq_dispatcher);

    /* Open the AC97 controller channel #1 */
    if ((ac97dev1 = ac97_open(AAC, 0)) == (INT_32) NULL)
    {
        return 0;
    }

    /* Reset AC97 CODEC power and allow a small delay (300mS) for
       device to re-initialize correctly */
    ac97_ioctl(ac97dev1, AC97_DO_RESET, 1);
    timer_wait_us(TIMER1, (300 * 1000));

    /* Make sure all DMA channels are disabled */
    for (dmach = DMAC_USB_RX; dmach <= DMAC_UART_TX3; dmach++)
    {
        dmac_stop(dmach);
    }

    /* Install (all) DMA handlers in the IRQ dispatcher */
    for (vici = VIC_DMA_M2PCH0; vici <= VIC_DMA_M2MCH1; vici++)
    {
        vic_install_handler(vici, VIC_IRQ, (PFV) dmac_isr);
    }
    
    /* Enable IRQ interrupts in the ARM core */
    enable_irq();

    /* Set CODEC volumes to MAX (all CODEC outputs) */
    vol.mute   = FALSE;
    vol.left   = AC97_MAX_VOL;
    vol.right  = AC97_MAX_VOL;
    vol.select = MASTER_OUT;
    ac97_ioctl(ac97dev1, AC97_SET_VOL, (INT_32) &vol);
    vol.select = AUX_OUT;
    ac97_ioctl(ac97dev1, AC97_SET_VOL, (INT_32) &vol);
    vol.select = MONO_OUT;
    ac97_ioctl(ac97dev1, AC97_SET_VOL, (INT_32) &vol);

    /* Mute all CODEC mixer channels */
    mix.mute   = FALSE;
    mix.left   = AC97_MIX_GN_MAX; // TBD MAX GAIN SB MIN
    mix.right  = AC97_MIX_GN_MAX; // TBD MAX GAIN SB MIN
    for (xa = BEEP_OUT; xa < PCM_OUT; xa++)
    {
        mix.select = (AC97_MIX_GAIN_SEL_T) xa;
        ac97_ioctl(ac97dev1, AC97_SET_MIXGAIN, (INT_32) &mix);
    }

    /* Set PCM output channel to max gain in mixer (volume) */
    mix.mute   = FALSE;
    mix.left   = AC97_REC_GN_MAX;
    mix.right  = AC97_REC_GN_MAX;
    mix.select = PCM_OUT;
    ac97_ioctl(ac97dev1, AC97_SET_MIXGAIN, (INT_32) &mix);

    /* Use maximum gain for line input */
    mix.select = LINE_IN;
    ac97_ioctl(ac97dev1, AC97_SET_MIXGAIN, (INT_32) &mix);

    /* Select line in as the recording device */
    ac97_ioctl(ac97dev1, AC97_SET_RCHAN, (INT_32) LINE_IN_SEL);

    /* Set maximum recording gain */
    recgain.left_gain  = AC97_REC_GN_MAX;
    recgain.right_gain = AC97_REC_GN_MAX;
    ac97_ioctl(ac97dev1, AC97_SET_RECGAIN, (INT_32) &recgain);

    /* Set bass and treble tone control to bypass - this is not
       supported on the Wolfson 9708 CODEC, but there should be no
       problems attempting to issue the command */
    tone.bass_gain = AC97_TONE_BYPASS;
    tone.treble_gain = AC97_TONE_BYPASS;
    ac97_ioctl(ac97dev1, AC97_SET_TONE, (INT_32) &tone);

    /* Setup channel for record */
    chcfg.srate = BPSEC_8000;
    chcfg.ssize = BPSAM_16;
    chcfg.compact = FALSE;
    chcfg.dir = RECORD;
    chcfg.tmode = AC97_DMA;
    chcfg.channels = 2;
    ac97_ioctl(ac97dev1, AC97_SET_CHANNEL, (INT_32) &chcfg);

    /* Configure the AC97 for DMA audio record. The DMA channel
       will be returned by this call when tmode is set to AC97_DMA
       as the transfer mode */
    dmach = (DMAC_CHANNEL_T)
        ac97_ioctl(ac97dev1, AC97_SET_CHANNEL, (INT_32) &chcfg);

    /* The DMA controller requires physical address, so translate
       the audio data to a physical address first */
    phyaddr = (UNS_32 *)
        cp15_map_virtual_to_physical((UNS_32 *) sound_data);
        
    /* For the selected DMA channel, start the transfer */
    dmac_start(dmach, phyaddr, sizeof(sound_data), TRUE);

    /* Check for DMA sample to complete by monitoring the DMA
       status */
    while (dmac_get_status(dmach) != DMA_DISABLED);

    /* Stop DMA */
    dmac_stop(dmach);

    /* Mute the line in channel */
    mix.mute   = TRUE;
    ac97_ioctl(ac97dev1, AC97_SET_MIXGAIN, (INT_32) &mix);

    /* Now setup channel for playback at a slower rate */
    chcfg.srate = BPSEC_8000;
    chcfg.dir = PLAYBACK;

    /* Play sample 3 times at different rates */
    for (loop = 0; loop < 3; loop++)
    {
        /* Configure the AC97 for DMA audio playback */
        dmach = (DMAC_CHANNEL_T)
            ac97_ioctl(ac97dev1, AC97_SET_CHANNEL, (INT_32) &chcfg);

        /* For the selected DMA channel, start the transfer */
        dmac_start(dmach, phyaddr, sizeof(sound_data), TRUE);

        /* Check for DMA sample to complete by monitoring the DMA
           status */
        while (dmac_get_status(dmach) != DMA_DISABLED);

        /* Stop DMA */
        dmac_stop(dmach);

        /* A little faster now */
        chcfg.srate++;
    }

    return 1;
}

#ifndef __GNUC__
/* With ARM and GHS toolsets, the entry point is main() - this will
   allow the linker to generate wrapper code to setup stacks, allocate
   heap area, and initialize and copy code and data segments. For GNU
   toolsets, the entry point is through __start() in the crt0_gnu.asm
   file, and that startup code will setup stacks and data */
int main(void)
{
    return c_entry();
}
#endif

⌨️ 快捷键说明

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