Library untuk WAU8822 pada Nuvoton LB-140

Berikut contoh library untuk WAU8822 pada Nuvoton LB-140

Penggunaan:

#include "NUC100Series.h"
    void main (void){
    SYS_UnlockReg(); // Unlock protected registers
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk | CLK_PWRCON_OSC10K_EN_Msk ); // Enable HXT external 12MHz cyrstal
    CLK_SetCoreClock(50000000);    //  Set HCLK frequency 50MHz
    SYS_LockReg(); // Lock protected registers

    //I2C - I2S WAU8822 codec
    WAU8822_Config();

    GPIO_SetMode(PE, BIT14, GPIO_PMD_OUTPUT);
    PE14=0;  //PHone OUT Enable (NUC-LB-140)

#ifdef POOLING
    //open I2S function
    //st.u32SampleRate     = 16000;
    //st.u8WordWidth       = I2S_DATABIT_16;
    //st.u8AudioFormat     = I2S_STEREO;
    //st.u8DataFormat      = I2S_FORMAT_I2S;
    //st.u8Mode            = I2S_MODE_SLAVE;
    //st.u8TxFIFOThreshold = I2S_FIFO_TX_LEVEL_WORD_0;
    //st.u8RxFIFOThreshold = I2S_FIFO_RX_LEVEL_WORD_8;//SMP_ONE
    I2S_Open(I2S,I2S_MODE_MASTER,32000,I2S_DATABIT_16,I2S_STEREO,I2S_FORMAT_I2S);

    // Set MCLK and enable MCLK
    I2S_EnableMCLK(I2S,6000000);

    while(1)
    {
            if((I2S->STATUS & I2S_STATUS_TXFULL_Msk) == 0)
            {
               //write your code here
            }
    }
#else   //interrupt

    //interrupt
    I2S_Open(I2S,I2S_MODE_SLAVE,32000,I2S_DATABIT_16,I2S_STEREO,I2S_FORMAT_I2S);
    I2S_EnableMCLK(I2S,12000000);

    I2S_EnableInt(I2S,I2S_IE_RXTHIE_Msk );
    NVIC_EnableIRQ(I2S_IRQn);
    
    while(1){}
#endif
}

void I2S_IRQHandler(void)
{
    /* Fill sin samples to I2S until Tx FIFO full */
    while((I2S->STATUS & I2S_STATUS_TXFULL_Msk) == 0)
    {
         //write your interrupt code here
    }
}

wau8822n.h

 #ifndef WAU8822N_H
 #define WAU8822N_H

#include "NUC100Series.h"
 #include "gpio.h"

#define WAU8822_INIT_MASTER 0x1
 #define WAU8822_INIT_SLAVE 0x2
 #define WAU8822_INIT_IN_LINE_L 0x4
 #define WAU8822_INIT_IN_LINE_R 0x8
 #define WAU8822_INIT_IN_MIC_L 0x10
 #define WAU8822_INIT_IN_MIC_R 0x20
 #define WAU8822_INIT_IN_AUX_L 0x40
 #define WAU8822_INIT_IN_AUX_R 0x80
 #define WAU8822_INIT_OUT_HP_L 0x100
 #define WAU8822_INIT_OUT_HP_R 0x200
 #define WAU8822_INIT_OUT_AUX1 0x400
 #define WAU8822_INIT_OUT_AUX2 0x800

#define WAU8822_INIT_SR8000 0x1000
 #define WAU8822_INIT_SR12000 0x2000
 #define WAU8822_INIT_SR16000 0x4000
 #define WAU8822_INIT_SR24000 0x8000
 #define WAU8822_INIT_SR32000 0x10000
 #define WAU8822_INIT_SR48000 0x20000

void I2C_WriteWAU8822(uint8_t regAddr, uint16_t u16data);
 void WAU8822_Init(uint32_t u32Option);
 void WAU8822_Config(void);

#endif

wau8822n.c

#include "wau8822n.h"

void I2C_WriteWAU8822(uint8_t regAddr, uint16_t u16data)
{
    I2C_START(I2C0);                            //Start
    I2C_WAIT_READY(I2C0);                        //Wait action completed

    I2C_SET_DATA(I2C0,  0x34);                    //set WAU8822 I2C address
    I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);     //Set SI (transfer data)
    I2C_WAIT_READY(I2C0);                        //Wait action completed

    I2C_SET_DATA(I2C0, (uint8_t)((regAddr << 1) | (u16data >> 8)));  //set I2Cdata w/  reg address shifted << 1, + data bit 8
    I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI | I2C_I2CON_AA);          //Set SI and AA (transfer data with Acknowledge)
    I2C_WAIT_READY(I2C0);                        //Wait action completed

    I2C_SET_DATA(I2C0, (uint8_t)(u16data & 0x00FF) );                //set I2Cdata w/ data bit 7:0
    I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI | I2C_I2CON_AA);         //Set SI and AA (transfer data with Acknowledge)
    I2C_WAIT_READY(I2C0);                        //Wait action completed

    I2C_STOP(I2C0);                                //Stop

}


void WAU8822_Init(uint32_t u32Option)
{
    uint32_t u32Reg;

    I2C_WriteWAU8822(0, 0x000);//Reset

    u32Reg = 0x00B;
    if(u32Option & WAU8822_INIT_MASTER)
        u32Reg |= 0x020; // Enable PLL in Master mode
    if(u32Option & WAU8822_INIT_OUT_AUX1)
        u32Reg |= 0x084; // For AUX1 Output
    if(u32Option & WAU8822_INIT_OUT_AUX2)
        u32Reg |= 0x044; // For AUX2 Output
    if(u32Option & (WAU8822_INIT_IN_MIC_L | WAU8822_INIT_IN_MIC_R))
        u32Reg |= 0x010; // For MIC Bias output
    I2C_WriteWAU8822(1, u32Reg);

    u32Reg = 0;
    if(u32Option & WAU8822_INIT_OUT_HP_L)
        u32Reg |= 0x080; // Enable Headphone Left output
    if(u32Option & WAU8822_INIT_OUT_HP_R)
        u32Reg |= 0x100; // Enable Headphone Right output
    if(u32Option & (WAU8822_INIT_IN_LINE_L | WAU8822_INIT_IN_MIC_L | WAU8822_INIT_IN_AUX_L))
        u32Reg |= 0x011; // Enable LADC Mix/Boost & Left ADC
    if(u32Option & (WAU8822_INIT_IN_LINE_R | WAU8822_INIT_IN_MIC_R | WAU8822_INIT_IN_AUX_R))
        u32Reg |= 0x022; // Enable RADC Mix/Boost & Right ADC
    if(u32Option & WAU8822_INIT_IN_MIC_L)
        u32Reg |= 0x004; // Enable Left PGA
    if(u32Option & WAU8822_INIT_IN_MIC_R)
        u32Reg |= 0x008; // Enable Right PGA
    I2C_WriteWAU8822(2, u32Reg);

    u32Reg = 0;
    if(u32Option & WAU8822_INIT_OUT_AUX1)
        u32Reg |= 0x102; // Enable AUX1 & RDAC
    if(u32Option & WAU8822_INIT_OUT_AUX2)
        u32Reg |= 0x081; // Enable AUX2 & LDAC
    if(u32Option & WAU8822_INIT_OUT_HP_L)
        u32Reg |= 0x005; // Eanble LMIX & LDAC
    if(u32Option & WAU8822_INIT_OUT_HP_R)
        u32Reg |= 0x00A; // Eanble RMIX & RDAC
    I2C_WriteWAU8822(3, u32Reg);

    I2C_WriteWAU8822(4,  0x010);// I2S 16-bit format

    I2C_WriteWAU8822(10,  0x000);

    I2C_WriteWAU8822(5,  0x000);//R5 companding ctrl and loop back mode (all disable)

    if(u32Option & WAU8822_INIT_MASTER)
    {
        // Codec works as an Master

        // MCLK = 6MHz
        I2C_WriteWAU8822(36, 0x008);
        I2C_WriteWAU8822(37, 0x00C);
        I2C_WriteWAU8822(38, 0x093);
        I2C_WriteWAU8822(39, 0x0E9);
        if(u32Option & WAU8822_INIT_SR8000)
        {
            I2C_WriteWAU8822(6 , 0x1AD);
            I2C_WriteWAU8822(7 , 0x00A);
        }
        else if(u32Option & WAU8822_INIT_SR12000)
        {
            I2C_WriteWAU8822(6 , 0x18D);
            I2C_WriteWAU8822(7 , 0x008);
        }
        else if(u32Option & WAU8822_INIT_SR16000)
        {
            I2C_WriteWAU8822(6 , 0x16D);
            I2C_WriteWAU8822(7 , 0x006);
        }
        else if(u32Option & WAU8822_INIT_SR24000)
        {
            I2C_WriteWAU8822(6 , 0x14D);
            I2C_WriteWAU8822(7 , 0x004);
        }
        else if(u32Option & WAU8822_INIT_SR32000)
        {
            I2C_WriteWAU8822(6 , 0x12D);
            I2C_WriteWAU8822(7 , 0x002);
        }
        else if(u32Option & WAU8822_INIT_SR48000)
        {
            I2C_WriteWAU8822(6 , 0x10D);
            I2C_WriteWAU8822(7 , 0x000);
        }
    }
    else
    {
        I2C_WriteWAU8822(6 , 0x000);
        if(u32Option & WAU8822_INIT_SR8000)
        {
            I2C_WriteWAU8822(7 , 0x00A);
        }
        else if(u32Option & WAU8822_INIT_SR16000)
        {
            I2C_WriteWAU8822(7 , 0x006);
        }
        else if(u32Option & WAU8822_INIT_SR24000)
        {
            I2C_WriteWAU8822(7 , 0x004);
        }
        else if(u32Option & WAU8822_INIT_SR32000)
        {
            I2C_WriteWAU8822(7 , 0x002);
        }
        else if(u32Option & WAU8822_INIT_SR48000)
        {
            I2C_WriteWAU8822(7 , 0x000);
        }
    }

    I2C_WriteWAU8822(8 , 0x034);

    I2C_WriteWAU8822(59, 0x000);
    I2C_WriteWAU8822(60, 0x020);
    I2C_WriteWAU8822(61, 0x000);

    I2C_WriteWAU8822(10, 0x009);//R10 DAC control (softmute disable, oversample select 128x)
    I2C_WriteWAU8822(43, 0x020);//speaker mute

    u32Reg = 0;
    if(u32Option & WAU8822_INIT_IN_MIC_L)
        u32Reg |= 0x003; // Connect LMICP, LMICN to LPGA
    if(u32Option & WAU8822_INIT_IN_MIC_R)
        u32Reg |= 0x030; // Connect RMICP, RMICN to RPGA
    I2C_WriteWAU8822(44, u32Reg);

//
// MIC input gain control
//
    u32Reg = 0;
    if(u32Option & WAU8822_INIT_IN_MIC_L)
        I2C_WriteWAU8822(45, 0x110); // MIC LPGA Gain 0dB
    else
        I2C_WriteWAU8822(45, 0x140); // MIC LPGA Mute

    u32Reg = 0;
    if(u32Option & WAU8822_INIT_IN_MIC_R)
        I2C_WriteWAU8822(46, 0x110); // MIC RPGA Gain 0dB
    else
        I2C_WriteWAU8822(46, 0x140); // MIC RPGA Mute

//
// Line In gain control
//
    u32Reg = 0;
    if(u32Option & WAU8822_INIT_IN_LINE_L)
        u32Reg |= 0x050; // LINE LPGA Gain 0dB
    if(u32Option & WAU8822_INIT_IN_AUX_L)
        u32Reg |= 0x005; // AUX LPGA Gain 0dB
    I2C_WriteWAU8822(47, u32Reg);

    u32Reg = 0;
    if(u32Option & WAU8822_INIT_IN_LINE_R)
        u32Reg |= 0x050; // LINE RPGA Gain 0dB
    if(u32Option & WAU8822_INIT_IN_AUX_R)
        u32Reg |= 0x005; // AUX RPGA Gain 0dB
    I2C_WriteWAU8822(48, u32Reg);


    I2C_WriteWAU8822(49, 0x01E);

    I2C_WriteWAU8822(50, 0x001);//R50 DACL2LMIX
    I2C_WriteWAU8822(51, 0x001);//R51 DACR2RMIX

//
// For Headphone Output
//

     // Left headphone volume/mute control
    if(u32Option & WAU8822_INIT_OUT_HP_L)
        I2C_WriteWAU8822(52, 0x039);
    else
        I2C_WriteWAU8822(52, 0x079);

     // Right headphone volume/mute control
    if(u32Option & WAU8822_INIT_OUT_HP_R)
        I2C_WriteWAU8822(53, 0x139);
    else
        I2C_WriteWAU8822(53, 0x179);

//
// For AUX output
//
    if(u32Option & WAU8822_INIT_OUT_AUX2)
        I2C_WriteWAU8822(56, 0x001); // LDAC to AUX2
    else
        I2C_WriteWAU8822(56, 0x040); // AUX2 Mute

    if(u32Option & WAU8822_INIT_OUT_AUX1)
        I2C_WriteWAU8822(57, 0x001); // RDAC to AUX1
    else
        I2C_WriteWAU8822(57, 0x040);// AUX1 Mute

    I2C_WriteWAU8822(11, 0x0FF); // LDAC Volume
    I2C_WriteWAU8822(12, 0x1FF); // RDAC Volume

    I2C_WriteWAU8822(54, 0x040);
    I2C_WriteWAU8822(55, 0x140);

    // high pass eanble
    I2C_WriteWAU8822(14, 0x180);

    /* Disable EQ and 3D */
    I2C_WriteWAU8822(41, 0x000); // No 3D
    I2C_WriteWAU8822(18, 0x02C);
    I2C_WriteWAU8822(19, 0x02C);
    I2C_WriteWAU8822(20, 0x02C);
    I2C_WriteWAU8822(21, 0x02C);
    I2C_WriteWAU8822(22, 0x02C);

}


void WAU8822_Config(void)
{
    //Set I2C0 source Clock to default with no Divider
     CLK_SetModuleClock(I2C0_MODULE, 0, 0);
     //Enable I2C0
     CLK_EnableModuleClock(I2C0_MODULE);
    // Set I2C I/O
    SYS->GPA_MFP |= SYS_GPA_MFP_PA8_I2C0_SDA;
    SYS->GPA_MFP |= SYS_GPA_MFP_PA9_I2C0_SCL;
     // Open I2C0, and set clock = 100Kbps
    I2C_Open(I2C0, 100000);
    // Enable I2C0 interrupt and set corresponding NVIC bit
    I2C_EnableInt(I2C0);


    // Setup wau8822 codec - I2C
    //WAU8822_Setup();
    WAU8822_Init(WAU8822_INIT_MASTER | WAU8822_INIT_SR32000
            | WAU8822_INIT_OUT_HP_L | WAU8822_INIT_OUT_HP_R
            //| WAU8822_INIT_IN_MIC_L
            | WAU8822_INIT_IN_AUX_L | WAU8822_INIT_IN_AUX_R
                );

    CLK_SetModuleClock(I2S_MODULE,CLK_CLKSEL2_I2S_S_HXT,0);
    CLK_EnableModuleClock(I2S_MODULE);

    SYS->GPA_MFP = SYS_GPA_MFP_PA15_I2S_MCLK;
    SYS->GPC_MFP = SYS_GPC_MFP_PC0_I2S_LRCLK | SYS_GPC_MFP_PC1_I2S_BCLK | SYS_GPC_MFP_PC2_I2S_DI | SYS_GPC_MFP_PC3_I2S_DO;
    SYS->ALT_MFP = SYS_ALT_MFP_PA15_I2S_MCLK | SYS_ALT_MFP_PC0_I2S_LRCLK | SYS_ALT_MFP_PC1_I2S_BCLK | SYS_ALT_MFP_PC2_I2S_DI | SYS_ALT_MFP_PC3_I2S_DO;

    // Tri-state for FS and BCLK of CODEC
    GPIO_SetMode(PC, BIT0,  GPIO_PMD_OPEN_DRAIN);PC0 = 1;
    GPIO_SetMode(PC, BIT1, GPIO_PMD_OPEN_DRAIN);PC1 = 1;

}

portinit.h

#ifndef _INITIALIZATION_H
#define _INITIALIZATION_H

enum {GPIOPIN,
    ADC0PIN, ADC1PIN, ADC2PIN, ADC3PIN, ADC4PIN, ADC5PIN, ADC6PIN, ADC7PIN,
    SPI0PORT, SPI1PORT, SPI2PORT, SPI3PORT};

extern void Port_Init(uint32_t pinName);
#endif

PortInitNUC140.c

#include <stdio.h>
#include "NUC100Series.h"
#include "portinit.h"

extern void Port_Init(uint32_t pinName){
    switch(pinName){
    case ADC7PIN:
            // Configure the GPA7 ADC analog input pins
            SYS->GPA_MFP &= ~(SYS_GPA_MFP_PA7_Msk);
            SYS->GPA_MFP |= SYS_GPA_MFP_PA7_ADC7;
            // Disable the GPA7 digital input path to avoid the leakage current.
            GPIO_DISABLE_DIGITAL_PATH(PA, SYS_GPA_MFP_PA7_Msk);
            break;
    case SPI1PORT:
        SYS->GPC_MFP &= ~(SYS_GPC_MFP_PC8_Msk | SYS_GPC_MFP_PC9_Msk | SYS_GPC_MFP_PC10_Msk | SYS_GPC_MFP_PC11_Msk);
        SYS->GPC_MFP |=  (SYS_GPC_MFP_PC8_SPI1_SS0 | SYS_GPC_MFP_PC9_SPI1_CLK | SYS_GPC_MFP_PC10_SPI1_MISO0 | SYS_GPC_MFP_PC11_SPI1_MOSI0);
        break;
    case SPI2PORT:
        // Setup SPI3 multi-function pins
        SYS->GPD_MFP = (SYS->GPD_MFP & ~(SYS_GPD_MFP_PD0_Msk | SYS_GPD_MFP_PD1_Msk | SYS_GPD_MFP_PD2_Msk | SYS_GPD_MFP_PD3_Msk)) |
                       (SYS_GPD_MFP_PD0_SPI2_SS0 | SYS_GPD_MFP_PD1_SPI2_CLK | SYS_GPD_MFP_PD2_SPI2_MISO0 | SYS_GPD_MFP_PD3_SPI2_MOSI0);
        break;
    case SPI3PORT:
        // Setup SPI3 multi-function pins
        SYS->GPD_MFP = (SYS->GPD_MFP & ~(SYS_GPD_MFP_PD8_Msk | SYS_GPD_MFP_PD9_Msk | SYS_GPD_MFP_PD10_Msk | SYS_GPD_MFP_PD11_Msk)) |
                       (SYS_GPD_MFP_PD8_SPI3_SS0 | SYS_GPD_MFP_PD9_SPI3_CLK | SYS_GPD_MFP_PD10_SPI3_MISO0 | SYS_GPD_MFP_PD11_SPI3_MOSI0);
        break;


    default:
        break;
    }
}

 

2 thoughts on “Library untuk WAU8822 pada Nuvoton LB-140

  1. Hi, I am going to study about this LB02 Nuc140 board.
    and I have something that not understand about WAU8822, Could u give me some advances, how the WAU8822 work?
    Thank you!

Comments are closed.