lpc-field

Template project for programming NXP's LPC1768 MCUs
git clone git://git.mdnr.space/lpc-field
Log | Files | Refs | README | LICENSE

lpc17xx_i2s.c (21475B)


      1 /**********************************************************************
      2 * $Id$		lpc17xx_i2s.c				2010-09-23
      3 *//**
      4 * @file		lpc17xx_i2s.c
      5 * @brief	Contains all functions support for I2S firmware
      6 * 			library on LPC17xx
      7 * @version	3.1
      8 * @date		23. Sep. 2010
      9 * @author	NXP MCU SW Application Team
     10 *
     11 * Copyright(C) 2010, NXP Semiconductor
     12 * All rights reserved.
     13 *
     14 ***********************************************************************
     15 * Software that is described herein is for illustrative purposes only
     16 * which provides customers with programming information regarding the
     17 * products. This software is supplied "AS IS" without any warranties.
     18 * NXP Semiconductors assumes no responsibility or liability for the
     19 * use of the software, conveys no license or title under any patent,
     20 * copyright, or mask work right to the product. NXP Semiconductors
     21 * reserves the right to make changes in the software without
     22 * notification. NXP Semiconductors also make no representation or
     23 * warranty that such application will be suitable for the specified
     24 * use without further testing or modification.
     25 * Permission to use, copy, modify, and distribute this software and its
     26 * documentation is hereby granted, under NXP Semiconductors'
     27 * relevant copyright in the software, without fee, provided that it
     28 * is used in conjunction with NXP Semiconductors microcontrollers.  This
     29 * copyright, permission, and disclaimer notice must appear in all copies of
     30 * this code.
     31 **********************************************************************/
     32 
     33 /* Peripheral group ----------------------------------------------------------- */
     34 /** @addtogroup I2S
     35  * @{
     36  */
     37 
     38 /* Includes ------------------------------------------------------------------- */
     39 #include "lpc17xx_i2s.h"
     40 #include "lpc17xx_clkpwr.h"
     41 
     42 
     43 /* If this source file built with example, the LPC17xx FW library configuration
     44  * file in each example directory ("lpc17xx_libcfg.h") must be included,
     45  * otherwise the default FW library configuration file must be included instead
     46  */
     47 #ifdef __BUILD_WITH_EXAMPLE__
     48 #include "lpc17xx_libcfg.h"
     49 #else
     50 #include "lpc17xx_libcfg_default.h"
     51 #endif /* __BUILD_WITH_EXAMPLE__ */
     52 
     53 
     54 #ifdef _I2S
     55 
     56 /* Private Functions ---------------------------------------------------------- */
     57 
     58 static uint8_t i2s_GetWordWidth(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode);
     59 static uint8_t i2s_GetChannel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode);
     60 
     61 /********************************************************************//**
     62  * @brief		Get I2S wordwidth value
     63  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
     64  * @param[in]	TRMode is the I2S mode, should be:
     65  * 				- I2S_TX_MODE = 0: transmit mode
     66  * 				- I2S_RX_MODE = 1: receive mode
     67  * @return 		The wordwidth value, should be: 8,16 or 32
     68  *********************************************************************/
     69 static uint8_t i2s_GetWordWidth(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
     70 	uint8_t value;
     71 
     72 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
     73 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
     74 
     75 	if (TRMode == I2S_TX_MODE) {
     76 		value = (I2Sx->I2SDAO) & 0x03; /* get wordwidth bit */
     77 	} else {
     78 		value = (I2Sx->I2SDAI) & 0x03; /* get wordwidth bit */
     79 	}
     80 	switch (value) {
     81 	case I2S_WORDWIDTH_8:
     82 		return 8;
     83 	case I2S_WORDWIDTH_16:
     84 		return 16;
     85 	default:
     86 		return 32;
     87 	}
     88 }
     89 
     90 /********************************************************************//**
     91  * @brief		Get I2S channel value
     92  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
     93  * @param[in]	TRMode is the I2S mode, should be:
     94  * 				- I2S_TX_MODE = 0: transmit mode
     95  * 				- I2S_RX_MODE = 1: receive mode
     96  * @return 		The channel value, should be: 1(mono) or 2(stereo)
     97  *********************************************************************/
     98 static uint8_t i2s_GetChannel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
     99 	uint8_t value;
    100 
    101 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    102 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    103 
    104 	if (TRMode == I2S_TX_MODE) {
    105 		value = ((I2Sx->I2SDAO) & 0x04)>>2; /* get bit[2] */
    106 	} else {
    107 		value = ((I2Sx->I2SDAI) & 0x04)>>2; /* get bit[2] */
    108 	}
    109         if(value == I2S_MONO) return 1;
    110           return 2;
    111 }
    112 
    113 /* End of Private Functions --------------------------------------------------- */
    114 
    115 
    116 /* Public Functions ----------------------------------------------------------- */
    117 /** @addtogroup I2S_Public_Functions
    118  * @{
    119  */
    120 
    121 /********************************************************************//**
    122  * @brief		Initialize I2S
    123  * 					- Turn on power and clock
    124  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    125  * @return 		none
    126  *********************************************************************/
    127 void I2S_Init(LPC_I2S_TypeDef *I2Sx) {
    128 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    129 
    130 	// Turn on power and clock
    131 	CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, ENABLE);
    132 	LPC_I2S->I2SDAI = LPC_I2S->I2SDAO = 0x00;
    133 }
    134 
    135 /********************************************************************//**
    136  * @brief		Configuration I2S, setting:
    137  * 					- master/slave mode
    138  * 					- wordwidth value
    139  * 					- channel mode
    140  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    141  * @param[in]	TRMode transmit/receive mode, should be:
    142  * 					- I2S_TX_MODE = 0: transmit mode
    143  * 					- I2S_RX_MODE = 1: receive mode
    144  * @param[in]	ConfigStruct pointer to I2S_CFG_Type structure
    145  *              which will be initialized.
    146  * @return 		none
    147  *********************************************************************/
    148 void I2S_Config(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, I2S_CFG_Type* ConfigStruct)
    149 {
    150 	uint32_t bps, config;
    151 
    152 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    153 
    154 	CHECK_PARAM(PARAM_I2S_WORDWIDTH(ConfigStruct->wordwidth));
    155 	CHECK_PARAM(PARAM_I2S_CHANNEL(ConfigStruct->mono));
    156 	CHECK_PARAM(PARAM_I2S_STOP(ConfigStruct->stop));
    157 	CHECK_PARAM(PARAM_I2S_RESET(ConfigStruct->reset));
    158 	CHECK_PARAM(PARAM_I2S_WS_SEL(ConfigStruct->ws_sel));
    159 	CHECK_PARAM(PARAM_I2S_MUTE(ConfigStruct->mute));
    160 
    161 	/* Setup clock */
    162 	bps = (ConfigStruct->wordwidth +1)*8;
    163 
    164 	/* Calculate audio config */
    165 	config = (bps - 1)<<6 | (ConfigStruct->ws_sel)<<5 | (ConfigStruct->reset)<<4 |
    166 		(ConfigStruct->stop)<<3 | (ConfigStruct->mono)<<2 | (ConfigStruct->wordwidth);
    167 
    168 	if(TRMode == I2S_RX_MODE){
    169 		LPC_I2S->I2SDAI = config;
    170 	}else{
    171 		LPC_I2S->I2SDAO = config;
    172 	}
    173 }
    174 
    175 /********************************************************************//**
    176  * @brief		DeInitial both I2S transmit or receive
    177  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    178  * @return 		none
    179  *********************************************************************/
    180 void I2S_DeInit(LPC_I2S_TypeDef *I2Sx) {
    181 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    182 
    183 	// Turn off power and clock
    184 	CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, DISABLE);
    185 }
    186 
    187 /********************************************************************//**
    188  * @brief		Get I2S Buffer Level
    189  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    190  * @param[in]	TRMode Transmit/receive mode, should be:
    191  * 					- I2S_TX_MODE = 0: transmit mode
    192  * 					- I2S_RX_MODE = 1: receive mode
    193  * @return 		current level of Transmit/Receive Buffer
    194  *********************************************************************/
    195 uint8_t I2S_GetLevel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode)
    196 {
    197 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    198 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    199 
    200 	if(TRMode == I2S_TX_MODE)
    201 	{
    202 		return ((I2Sx->I2SSTATE >> 16) & 0xFF);
    203 	}
    204 	else
    205 	{
    206 		return ((I2Sx->I2SSTATE >> 8) & 0xFF);
    207 	}
    208 }
    209 
    210 /********************************************************************//**
    211  * @brief		I2S Start: clear all STOP,RESET and MUTE bit, ready to operate
    212  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    213  * @return 		none
    214  *********************************************************************/
    215 void I2S_Start(LPC_I2S_TypeDef *I2Sx)
    216 {
    217 	//Clear STOP,RESET and MUTE bit
    218 	I2Sx->I2SDAO &= ~I2S_DAI_RESET;
    219 	I2Sx->I2SDAI &= ~I2S_DAI_RESET;
    220 	I2Sx->I2SDAO &= ~I2S_DAI_STOP;
    221 	I2Sx->I2SDAI &= ~I2S_DAI_STOP;
    222 	I2Sx->I2SDAO &= ~I2S_DAI_MUTE;
    223 }
    224 
    225 /********************************************************************//**
    226  * @brief		I2S Send data
    227  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    228  * @param[in]	BufferData pointer to uint32_t is the data will be send
    229  * @return 		none
    230  *********************************************************************/
    231 void I2S_Send(LPC_I2S_TypeDef *I2Sx, uint32_t BufferData) {
    232 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    233 
    234 	I2Sx->I2STXFIFO = BufferData;
    235 }
    236 
    237 /********************************************************************//**
    238  * @brief		I2S Receive Data
    239  * @param[in]	I2Sx pointer to LPC_I2S_TypeDef
    240  * @return 		received value
    241  *********************************************************************/
    242 uint32_t I2S_Receive(LPC_I2S_TypeDef* I2Sx) {
    243 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    244 
    245 	return (I2Sx->I2SRXFIFO);
    246 
    247 }
    248 
    249 /********************************************************************//**
    250  * @brief		I2S Pause
    251  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    252  * @param[in]	TRMode is transmit/receive mode, should be:
    253  * 				- I2S_TX_MODE = 0: transmit mode
    254  * 				- I2S_RX_MODE = 1: receive mode
    255  * @return 		none
    256  *********************************************************************/
    257 void I2S_Pause(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
    258 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    259 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    260 
    261 	if (TRMode == I2S_TX_MODE) //Transmit mode
    262 	{
    263 		I2Sx->I2SDAO |= I2S_DAO_STOP;
    264 	} else //Receive mode
    265 	{
    266 		I2Sx->I2SDAI |= I2S_DAI_STOP;
    267 	}
    268 }
    269 
    270 /********************************************************************//**
    271  * @brief		I2S Mute
    272  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    273  * @param[in]	TRMode is transmit/receive mode, should be:
    274  * 				- I2S_TX_MODE = 0: transmit mode
    275  * 				- I2S_RX_MODE = 1: receive mode
    276  * @return 		none
    277  *********************************************************************/
    278 void I2S_Mute(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
    279 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    280 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    281 
    282 	if (TRMode == I2S_TX_MODE) //Transmit mode
    283 	{
    284 		I2Sx->I2SDAO |= I2S_DAO_MUTE;
    285 	} else //Receive mode
    286 	{
    287 		I2Sx->I2SDAI |= I2S_DAI_MUTE;
    288 	}
    289 }
    290 
    291 /********************************************************************//**
    292  * @brief		I2S Stop
    293  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    294  * @param[in]	TRMode is transmit/receive mode, should be:
    295  * 				- I2S_TX_MODE = 0: transmit mode
    296  * 				- I2S_RX_MODE = 1: receive mode
    297  * @return 		none
    298  *********************************************************************/
    299 void I2S_Stop(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) {
    300 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    301 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    302 
    303 	if (TRMode == I2S_TX_MODE) //Transmit mode
    304 	{
    305 		I2Sx->I2SDAO &= ~I2S_DAO_MUTE;
    306 		I2Sx->I2SDAO |= I2S_DAO_STOP;
    307 		I2Sx->I2SDAO |= I2S_DAO_RESET;
    308 	} else //Receive mode
    309 	{
    310 		I2Sx->I2SDAI |= I2S_DAI_STOP;
    311 		I2Sx->I2SDAI |= I2S_DAI_RESET;
    312 	}
    313 }
    314 
    315 /********************************************************************//**
    316  * @brief		Set frequency for I2S
    317  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    318  * @param[in]	Freq is the frequency for I2S will be set. It can range
    319  * 				from 16-96 kHz(16, 22.05, 32, 44.1, 48, 96kHz)
    320  * @param[in]	TRMode is transmit/receive mode, should be:
    321  * 				- I2S_TX_MODE = 0: transmit mode
    322  * 				- I2S_RX_MODE = 1: receive mode
    323  * @return 		Status: ERROR or SUCCESS
    324  *********************************************************************/
    325 Status I2S_FreqConfig(LPC_I2S_TypeDef *I2Sx, uint32_t Freq, uint8_t TRMode) {
    326 
    327 	uint32_t i2s_clk;
    328 	uint8_t channel, wordwidth;
    329 	uint32_t x, y;
    330 	uint64_t divider;
    331 	uint16_t dif;
    332 	uint16_t x_divide;
    333     uint16_t y_divide = 0;
    334 	uint16_t err, ErrorOptimal = 0xFFFF;
    335 	
    336 	uint32_t N;
    337 
    338 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    339 	CHECK_PARAM(PRAM_I2S_FREQ(Freq));
    340 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    341 
    342 	//Get the frequency of PCLK_I2S
    343 	i2s_clk = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_I2S);
    344 
    345 	if(TRMode == I2S_TX_MODE)
    346 	{
    347 		channel = i2s_GetChannel(I2Sx,I2S_TX_MODE);
    348 		wordwidth = i2s_GetWordWidth(I2Sx,I2S_TX_MODE);
    349 	}
    350 	else
    351 	{
    352 		channel = i2s_GetChannel(I2Sx,I2S_RX_MODE);
    353 		wordwidth = i2s_GetWordWidth(I2Sx,I2S_RX_MODE);
    354 	}
    355 
    356 	/* Calculate X and Y divider
    357 	 * The MCLK rate for the I2S transmitter is determined by the value
    358 	 * in the I2STXRATE/I2SRXRATE register. The required I2STXRATE/I2SRXRATE
    359 	 * setting depends on the desired audio sample rate desired, the format
    360 	 * (stereo/mono) used, and the data size.
    361 	 * The formula is:
    362 	 * 		I2S_MCLK = PCLK_I2S * (X/Y) / 2
    363      * In that, Y must be greater than or equal to X. X should divides evenly
    364      * into Y. 
    365 	 * We have:
    366 	 * 		I2S_MCLK = Freq * channel*wordwidth * (I2STXBITRATE+1);
    367 	 * So: (X/Y) = (Freq * channel*wordwidth * (I2STXBITRATE+1))*2/PCLK_I2S
    368 	 * We use a loop function to chose the most suitable X,Y value
    369 	 */
    370 
    371 	/* divider is a fixed point number with 16 fractional bits */
    372     divider = (((uint64_t)Freq *channel*wordwidth * 2)<<16) / i2s_clk;
    373 
    374 	/* find N that make x/y <= 1 -> divider <= 2^16 */
    375 	for(N=64;N>0;N--){
    376 		if((divider*N) < (1<<16)) break;
    377 	}
    378 
    379 	if(N == 0) return ERROR;
    380 
    381 	divider *= N;
    382 
    383 	for (y = 255; y > 0; y--) {
    384 		x = y * divider;
    385 		if(x & (0xFF000000)) continue;
    386 		dif = x & 0xFFFF;
    387 		if(dif>0x8000) err = 0x10000-dif;
    388 		else err = dif;
    389 		if (err == 0)
    390 		{
    391 			y_divide = y;
    392 			break;
    393 		}
    394 		else if (err < ErrorOptimal)
    395 		{
    396 			ErrorOptimal = err;
    397 			y_divide = y;
    398 		}
    399 	}
    400 	x_divide = ((uint64_t)y_divide * Freq *(channel*wordwidth)* N * 2)/i2s_clk;
    401 	if(x_divide >= 256) x_divide = 0xFF;
    402 	if(x_divide == 0) x_divide = 1;
    403 
    404 	if (TRMode == I2S_TX_MODE)// Transmitter
    405 	{
    406 		I2Sx->I2STXBITRATE = N-1;
    407 		I2Sx->I2STXRATE = y_divide | (x_divide << 8);
    408 	} else //Receiver
    409 	{
    410 		I2Sx->I2SRXBITRATE = N-1;
    411 		I2Sx->I2STXRATE = y_divide | (x_divide << 8);
    412 	}
    413 	return SUCCESS;
    414 }
    415 
    416 /********************************************************************//**
    417  * @brief		I2S set bitrate
    418  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    419  * @param[in]	bitrate value will be set
    420  * 				bitrate value should be in range: 0 .. 63
    421  * @param[in]	TRMode is transmit/receive mode, should be:
    422  * 				- I2S_TX_MODE = 0: transmit mode
    423  * 				- I2S_RX_MODE = 1: receive mode
    424  * @return 		none
    425  *********************************************************************/
    426 void I2S_SetBitRate(LPC_I2S_TypeDef *I2Sx, uint8_t bitrate, uint8_t TRMode)
    427 {
    428 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    429 	CHECK_PARAM(PARAM_I2S_BITRATE(bitrate));
    430 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    431 
    432 	if(TRMode == I2S_TX_MODE)
    433 	{
    434 		I2Sx->I2STXBITRATE = bitrate;
    435 	}
    436 	else
    437 	{
    438 		I2Sx->I2SRXBITRATE = bitrate;
    439 	}
    440 }
    441 
    442 /********************************************************************//**
    443  * @brief		Configuration operating mode for I2S
    444  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    445  * @param[in]	ModeConfig pointer to I2S_MODEConf_Type will be used to
    446  * 				configure
    447  * @param[in]	TRMode is transmit/receive mode, should be:
    448  * 				- I2S_TX_MODE = 0: transmit mode
    449  * 				- I2S_RX_MODE = 1: receive mode
    450  * @return 		none
    451  *********************************************************************/
    452 void I2S_ModeConfig(LPC_I2S_TypeDef *I2Sx, I2S_MODEConf_Type* ModeConfig,
    453 		uint8_t TRMode)
    454 {
    455 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    456 	CHECK_PARAM(PARAM_I2S_CLKSEL(ModeConfig->clksel));
    457 	CHECK_PARAM(PARAM_I2S_4PIN(ModeConfig->fpin));
    458 	CHECK_PARAM(PARAM_I2S_MCLK(ModeConfig->mcena));
    459 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    460 
    461 	if (TRMode == I2S_TX_MODE) {
    462 		I2Sx->I2STXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register
    463 		if (ModeConfig->clksel == I2S_CLKSEL_MCLK) {
    464 			I2Sx->I2STXMODE |= 0x02;
    465 		}
    466 		if (ModeConfig->fpin == I2S_4PIN_ENABLE) {
    467 			I2Sx->I2STXMODE |= (1 << 2);
    468 		}
    469 		if (ModeConfig->mcena == I2S_MCLK_ENABLE) {
    470 			I2Sx->I2STXMODE |= (1 << 3);
    471 		}
    472 	} else {
    473 		I2Sx->I2SRXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register
    474 		if (ModeConfig->clksel == I2S_CLKSEL_MCLK) {
    475 			I2Sx->I2SRXMODE |= 0x02;
    476 		}
    477 		if (ModeConfig->fpin == I2S_4PIN_ENABLE) {
    478 			I2Sx->I2SRXMODE |= (1 << 2);
    479 		}
    480 		if (ModeConfig->mcena == I2S_MCLK_ENABLE) {
    481 			I2Sx->I2SRXMODE |= (1 << 3);
    482 		}
    483 	}
    484 }
    485 
    486 /********************************************************************//**
    487  * @brief		Configure DMA operation for I2S
    488  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    489  * @param[in]	DMAConfig pointer to I2S_DMAConf_Type will be used to configure
    490  * @param[in]	TRMode is transmit/receive mode, should be:
    491  * 				- I2S_TX_MODE = 0: transmit mode
    492  * 				- I2S_RX_MODE = 1: receive mode
    493  * @return 		none
    494  *********************************************************************/
    495 void I2S_DMAConfig(LPC_I2S_TypeDef *I2Sx, I2S_DMAConf_Type* DMAConfig,
    496 		uint8_t TRMode)
    497 {
    498 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    499 	CHECK_PARAM(PARAM_I2S_DMA(DMAConfig->DMAIndex));
    500 	CHECK_PARAM(PARAM_I2S_DMA_DEPTH(DMAConfig->depth));
    501 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    502 
    503 	if (TRMode == I2S_RX_MODE) {
    504 		if (DMAConfig->DMAIndex == I2S_DMA_1) {
    505 			LPC_I2S->I2SDMA1 = (DMAConfig->depth) << 8;
    506 		} else {
    507 			LPC_I2S->I2SDMA2 = (DMAConfig->depth) << 8;
    508 		}
    509 	} else {
    510 		if (DMAConfig->DMAIndex == I2S_DMA_1) {
    511 			LPC_I2S->I2SDMA1 = (DMAConfig->depth) << 16;
    512 		} else {
    513 			LPC_I2S->I2SDMA2 = (DMAConfig->depth) << 16;
    514 		}
    515 	}
    516 }
    517 
    518 /********************************************************************//**
    519  * @brief		Enable/Disable DMA operation for I2S
    520  * @param[in]	I2Sx: I2S peripheral selected, should be: LPC_I2S
    521  * @param[in]	DMAIndex chose what DMA is used, should be:
    522  * 				- I2S_DMA_1 = 0: DMA1
    523  * 				- I2S_DMA_2 = 1: DMA2
    524  * @param[in]	TRMode is transmit/receive mode, should be:
    525  * 				- I2S_TX_MODE = 0: transmit mode
    526  * 				- I2S_RX_MODE = 1: receive mode
    527  * @param[in]	NewState is new state of DMA operation, should be:
    528  * 				- ENABLE
    529  * 				- DISABLE
    530  * @return 		none
    531  *********************************************************************/
    532 void I2S_DMACmd(LPC_I2S_TypeDef *I2Sx, uint8_t DMAIndex, uint8_t TRMode,
    533 		FunctionalState NewState)
    534 {
    535 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    536 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
    537 	CHECK_PARAM(PARAM_I2S_DMA(DMAIndex));
    538 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    539 
    540 	if (TRMode == I2S_RX_MODE) {
    541 		if (DMAIndex == I2S_DMA_1) {
    542 			if (NewState == ENABLE)
    543 				I2Sx->I2SDMA1 |= 0x01;
    544 			else
    545 				I2Sx->I2SDMA1 &= ~0x01;
    546 		} else {
    547 			if (NewState == ENABLE)
    548 				I2Sx->I2SDMA2 |= 0x01;
    549 			else
    550 				I2Sx->I2SDMA2 &= ~0x01;
    551 		}
    552 	} else {
    553 		if (DMAIndex == I2S_DMA_1) {
    554 			if (NewState == ENABLE)
    555 				I2Sx->I2SDMA1 |= 0x02;
    556 			else
    557 				I2Sx->I2SDMA1 &= ~0x02;
    558 		} else {
    559 			if (NewState == ENABLE)
    560 				I2Sx->I2SDMA2 |= 0x02;
    561 			else
    562 				I2Sx->I2SDMA2 &= ~0x02;
    563 		}
    564 	}
    565 }
    566 
    567 /********************************************************************//**
    568  * @brief		Configure IRQ for I2S
    569  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    570  * @param[in]	TRMode is transmit/receive mode, should be:
    571  * 				- I2S_TX_MODE = 0: transmit mode
    572  * 				- I2S_RX_MODE = 1: receive mode
    573  * @param[in]	level is the FIFO level that triggers IRQ request
    574  * @return 		none
    575  *********************************************************************/
    576 void I2S_IRQConfig(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, uint8_t level) {
    577 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    578 	CHECK_PARAM(PARAM_I2S_TRX(TRMode));
    579 	CHECK_PARAM(PARAM_I2S_IRQ_LEVEL(level));
    580 
    581 	if (TRMode == I2S_RX_MODE) {
    582 		I2Sx->I2SIRQ |= (level << 8);
    583 	} else {
    584 		I2Sx->I2SIRQ |= (level << 16);
    585 	}
    586 }
    587 
    588 /********************************************************************//**
    589  * @brief		Enable/Disable IRQ for I2S
    590  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    591  * @param[in]	TRMode is transmit/receive mode, should be:
    592  * 				- I2S_TX_MODE = 0: transmit mode
    593  * 				- I2S_RX_MODE = 1: receive mode
    594  * @param[in]	NewState is new state of DMA operation, should be:
    595  * 				- ENABLE
    596  * 				- DISABLE
    597  * @return 		none
    598  *********************************************************************/
    599 void I2S_IRQCmd(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, FunctionalState NewState) {
    600 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    601 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
    602 
    603 	if (TRMode == I2S_RX_MODE) {
    604 		if (NewState == ENABLE)
    605 			I2Sx->I2SIRQ |= 0x01;
    606 		else
    607 			I2Sx->I2SIRQ &= ~0x01;
    608 		//Enable DMA
    609 
    610 	} else {
    611 		if (NewState == ENABLE)
    612 			I2Sx->I2SIRQ |= 0x02;
    613 		else
    614 			I2Sx->I2SIRQ &= ~0x02;
    615 	}
    616 }
    617 
    618 /********************************************************************//**
    619  * @brief		Get I2S interrupt status
    620  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    621  * @param[in]	TRMode is transmit/receive mode, should be:
    622  * 				- I2S_TX_MODE = 0: transmit mode
    623  * 				- I2S_RX_MODE = 1: receive mode
    624  * @return 		FunctionState	should be:
    625  * 				- ENABLE: interrupt is enable
    626  * 				- DISABLE: interrupt is disable
    627  *********************************************************************/
    628 FunctionalState I2S_GetIRQStatus(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode)
    629 {
    630 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    631 	if(TRMode == I2S_TX_MODE)
    632 		return ((FunctionalState)((I2Sx->I2SIRQ >> 1)&0x01));
    633 	else
    634 		return ((FunctionalState)((I2Sx->I2SIRQ)&0x01));
    635 }
    636 
    637 /********************************************************************//**
    638  * @brief		Get I2S interrupt depth
    639  * @param[in]	I2Sx I2S peripheral selected, should be: LPC_I2S
    640  * @param[in]	TRMode is transmit/receive mode, should be:
    641  * 				- I2S_TX_MODE = 0: transmit mode
    642  * 				- I2S_RX_MODE = 1: receive mode
    643  * @return 		depth of FIFO level on which to create an irq request
    644  *********************************************************************/
    645 uint8_t I2S_GetIRQDepth(LPC_I2S_TypeDef *I2Sx,uint8_t TRMode)
    646 {
    647 	CHECK_PARAM(PARAM_I2Sx(I2Sx));
    648 	if(TRMode == I2S_TX_MODE)
    649 		return (((I2Sx->I2SIRQ)>>16)&0xFF);
    650 	else
    651 		return (((I2Sx->I2SIRQ)>>8)&0xFF);
    652 }
    653 /**
    654  * @}
    655  */
    656 
    657 #endif /* _I2S */
    658 
    659 /**
    660  * @}
    661  */
    662 
    663 /* --------------------------------- End Of File ------------------------------ */
    664