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;
}
}