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

📄 i2sdemo.c

📁 i2s usb audio demo lpc2138
💻 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 + -