📄 i2sdemo.c
字号:
/*****************************************************************************
* i2sDemo.c: main loop demo entry file - for NXP LPC23xx/24xx Family Microprocessors
* I2S Audio demo with UDA1341
*
* Copyright(C) 2007, NXP Semiconductor
* All rights reserved.
*
* History
* 2007.02.20 ver 1.00 Prelimnary version, first Release
*
******************************************************************************/
#include "stdio.h"
/* LPC23xx/24xx common header files */
#include "LPC23xx.h" /* LPC23xx/24xx definitions */
#include "type.h" /* LPC23xx/24xx definitions */
#include "irq.h" /* LPC23xx/24xx definitions */
#include "timer.h" /* LPC23xx/24xx definitions */
#include "../uart/inc/uart.h"
#include "../portLCD/inc/portLCD.h" /* Graphic LCD function prototypes */
#include "../i2s/inc/i2s.h"
#include "../L3/inc/L3.h"
#include "./inc/i2s_demo.h"
extern void key_HandlerDSS(void);
extern int I2S_muteFlag;
extern unsigned int accum;
/* functions in this file */
void I2S_Demo_main(void);
void I2S_Demo_parseKey(char ch);
int I2S_audio_play(void);
int I2S_audio_stopTX(void);
void I2S_config_Master(DWORD bitwidth);int I2S_config_TX(int config_index);
void I2S_config_Print(void);
/* global I2S variables */
volatile DWORD I2S_IRQ_count = 0;
volatile DWORD codec_status;
/* configuration for the I2S TX interfaces */
/* i2s_sample_rate, i2s_wordwidth, i2s_ws_sel, i2s_mono, i2s_ws_halfperiod */
const i2s_config_struct tx_config_table[] =
{
{ 44100, I2S_16BIT, I2S_SLAVE, I2S_STEREO, I2S_HALFWORD16,
"tx= 44.1kHz,16BIT,I2S_SLAVE, STEREO, HALFWORD15\r\n"},
};
const char welcome_msg[] = "\f\n\n\n\r"
" LPC2378 w/UDA1341 \n\n\r"
" AUDIO DEMO PROGRAM: \n\n\r"
" Direct Digital Synthesis \n\n\r"
#ifdef __DEBUG_RAM
" April 2007 (RAM version)\n\n\n\n\n\n\n\n\r"
#endif
#ifdef __DEBUG_FLASH
" April 2007 (Flash Version)\n\n\n\n\n\n\n\n\r"
#endif
"type \"h\" for help\r\n";
const char help_msg[] = "\f\n\n\rCommands:\r\n"
"S: Stop\r\n"
"P: Play\r\n"
"SPACE: Mute/Unmute\r\n"
"U: Display UDA1341 configuration\r\n"
"D: Display Audio configuration\r\n"
"+: Volume up\r\n"
"-: Volume down\r\n"
"H: Display this Help Message\r\n"
"N: Play Next Note\r\n"
"";
/* Message strings */
const char msg_codec_status[][40] =
{
" CODEC_STOP",
" CODEC_RECORD",
" CODEC_PLAYBACK",
" CODEC_LOOPBACK"
};
/* Start Demo */
/*******************************************************************************
*
* Function: void I2S_Demo_main(void) - Main demo loop for I2S DSS demo
*
*******************************************************************************/
void I2S_Demo_main(void)
{
char ch;
volatile int i;
/*msg*/
printf(welcome_msg);
/*start playback*/
I2S_config_TX(0);
I2S_audio_play();
accum=0;
/* this while loop checks for keypress on UART0 interface */
while(1)
{
ch = UART_GetChar(0); /* if keystroke parse request */
if ( ch != 0 ) I2S_Demo_parseKey(ch);
}
}
/*******************************************************************************
*
* Function: I2S_Demo_parseKey(char ch)
*
*******************************************************************************/
void I2S_Demo_parseKey(char ch)
{
if(ch == 'N' || ch == 'n') /* next note using keyboard. mono */
{
key_HandlerDSS();
return;
}
if(ch == 'S' || ch == 's') // stop TX audio
{
I2S_audio_stopTX();
printf("Audio Stopped\r\n");
return;
}
else if(ch == 'P' || ch == 'p') // Play TX audio
{
I2S_audio_stopTX();
I2S_audio_play();
printf("Audio Playback Started\r\n");
return;
}
else if(ch == 'U' || ch == 'u')
{
I2S_audio_stopTX();
printf("\fUDA1341 configuration:\n\n\r");
UDA1341_display();
I2S_audio_play();
return;
}
else if(ch == 'D' || ch == 'd') // display I2S conf
{
I2S_config_Print();
return;
}
else if(ch == ' ') // Mute / Unmute
{
if ((L3_data0[2] & L3d2_MT(1)) == L3d2_MT(1))
{
UDA1341_mute(0);
printf("UDA1341 Not Muted\r\n");
}
else
{
UDA1341_mute(1);
printf("UDA1341 Muted\r\n");
}
return;
}
else if(ch == '_' || ch == '-') // Volume down
{
UDA1341_volume_down_one();
printf("+1 = %d\r\n", L3_data0[0]);
return;
}
else if(ch == '=' || ch == '+') // Volume up
{
UDA1341_volume_up_one();
printf("-1 = %d\r\n", L3_data0[0]);
return;
}
else if(ch == 'H' || ch == 'h') // Help
{
I2S_audio_stopTX();
printf(help_msg);
I2S_audio_play();
return;
}
}
/*******************************************************************************
*
* Function: I2S_audio_play
*
*******************************************************************************/
int I2S_audio_play(void)
{
/*set status*/
codec_status = CODEC_PLAYBACK;
I2S_Enable_DAO(1);
return 1;
}
/*******************************************************************************
* Function: I2S_audio_stopTX
*
*******************************************************************************/
int I2S_audio_stopTX(void)
{
codec_status = CODEC_STOP;
i2s_enable_tx_irq(0); /* disable TX IRQ */ /* only needed if using I2S Irq */
I2S_Enable_DAO(0); /* disable : reset clear tx fifo and stop */
return 1;
}
/******************************************************************************** Function: I2S_config_Master - this function configures two timers to act
* as an I2S Master using external clock
*********************************************************************************/void I2S_config_Master(DWORD wordwidth){
while(L3Cmd != 0x0); /* Make sure Last interrupt driven L3 Command is complete */
disable_VIC_irq(TIMER0_INT);
disable_timer0();
disable_timer1();
switch(wordwidth)
{
case 0: /* 8-bit width */
init_timer1(16-1); /* timer 1 for I2S bitclk interface timing 22 Mhz */
// init_timer1(8-1); /* timer 1 for I2S bitclk interface timing 11 Mhz*/
init_timer0(8-1); /* timer 0 for L3 interface and I2S LRCLK; divide by 256=44.1k*/
break; case 1: /* 16-bit width */
init_timer1(8-1); /* timer 1 for I2S bitclk interface timing 22 Mhz*/
// init_timer1(4-1); /* timer 1 for I2S bitclk interface timing 11 Mhz */
init_timer0(16-1); /* timer 0 for L3 interface and I2S LRCLK; divide by 256=44.1k*/
break; case 2: /* reserved ignore*/
break; case 3: /* 32-bit width */
init_timer1(4-1); /* timer 1 for I2S bitclk interface 22 Mhz timing */
// init_timer1(2-1); /* timer 1 for I2S bitclk interface 11 Mhz timing */
init_timer0(32-1); /* timer 0 for L3 interface and I2S LRCLK; divide by 256=44.1k*/
break; default:
break;
}
reset_timer0(); /* reset timer0 */
reset_timer1(); /* reset timer1 */ enable_timer0(); /* enable timer0 */
enable_timer1(); /* enable timer1 */
enable_VIC_irq(TIMER0_INT);
}
/*******************************************************************************
*
* Function: I2S_config_TX - configures the I2S TX port based on current index
* into table tx_config_table
*
*******************************************************************************/
int I2S_config_TX(int config_index)
{
unsigned int txbitrate;
txbitrate = tx_config_table[config_index].sample_rate *
(tx_config_table[config_index].ws_halfperiod + 1) * 2 ;
disable_VIC_irq(I2S_INT); /* disable all I2S interrupts */
i2s_enable_tx_irq(0); /* disable i2s tx irq */
i2s_enable_rx_irq(0);
I2S_Enable_DAO(0); /* disable : reset clear tx and rx fifo and stop */
i2s_set_tx_depth_irq(I2S_TXFIFO_DEPTH);
/*config I2STXRATE register*/
I2S_config_Master(tx_config_table[config_index].wordwidth);
if (tx_config_table[config_index].ws_sel == I2S_MASTER )
i2s_config_txrate(txbitrate , DESIRED_FREQ_PCLK_I2S); /* used in master mode only */
/*config 23xx i2S DAO */
I2S_Config_DAO(tx_config_table[config_index].wordwidth,
tx_config_table[config_index].mono,
tx_config_table[config_index].ws_sel,
tx_config_table[config_index].ws_halfperiod);
return 1;
}
/*******************************************************************************
* Function: I2S_config_Print
*
*******************************************************************************/
void I2S_config_Print(void)
{
DWORD temp;
temp = codec_status;
I2S_audio_stopTX();
/**/
printf("Configuration:\n\n\r");
printf("CODEC STATUS:");
printf(msg_codec_status[temp]);
printf("\n\n\r");
/*print out the configuration*/
printf(tx_config_table[0].config_msg);
/*print volume info*/
printf("UDAS1341 Volume = %d\n\n\r", L3_data0[0] );
if( temp == CODEC_PLAYBACK) I2S_audio_play();
}
/*******************************************************************************
* Function: IRQ_I2S_service - determines if IRQ is for Record/loopback or Playback
* and switches to transfer routines (not used in
this demo)
*
*******************************************************************************/
void IRQ_I2S_service(void)
{
volatile DWORD I2S_Status;
I2S_IRQ_count++;
I2S_Status = I2S_STATE;
VICVectAddr = 0;
}
/*******************************************************************************
* END of FILE
*******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -