NXP's driver library for LPC17xx, ported to mbed's online compiler. Not tested! I had to fix a lot of warings and found a couple of pretty obvious bugs, so the chances are there are more. Original: http://ics.nxp.com/support/documents/microcontrollers/zip/lpc17xx.cmsis.driver.library.zip
lpc17xx_i2s.c
00001 /** 00002 * @file : lpc17xx_i2s.c 00003 * @brief : Contains all functions support for I2S firmware library on LPC17xx 00004 * @version : 1.0 00005 * @date : 13. May. 2009 00006 * @author : NguyenCao 00007 ************************************************************************** 00008 * Software that is described herein is for illustrative purposes only 00009 * which provides customers with programming information regarding the 00010 * products. This software is supplied "AS IS" without any warranties. 00011 * NXP Semiconductors assumes no responsibility or liability for the 00012 * use of the software, conveys no license or title under any patent, 00013 * copyright, or mask work right to the product. NXP Semiconductors 00014 * reserves the right to make changes in the software without 00015 * notification. NXP Semiconductors also make no representation or 00016 * warranty that such application will be suitable for the specified 00017 * use without further testing or modification. 00018 **********************************************************************/ 00019 00020 /* Peripheral group ----------------------------------------------------------- */ 00021 /** @addtogroup I2S 00022 * @{ 00023 */ 00024 00025 /* Includes ------------------------------------------------------------------- */ 00026 #include "lpc17xx_i2s.h" 00027 #include "lpc17xx_clkpwr.h" 00028 00029 00030 /* If this source file built with example, the LPC17xx FW library configuration 00031 * file in each example directory ("lpc17xx_libcfg.h") must be included, 00032 * otherwise the default FW library configuration file must be included instead 00033 */ 00034 #ifdef __BUILD_WITH_EXAMPLE__ 00035 #include "lpc17xx_libcfg.h" 00036 #else 00037 #include "lpc17xx_libcfg_default.h" 00038 #endif /* __BUILD_WITH_EXAMPLE__ */ 00039 00040 #ifdef __cplusplus 00041 extern "C" 00042 { 00043 #endif 00044 00045 #ifdef _I2S 00046 00047 /* Private Variables ---------------------------------------------------------- */ 00048 static fnI2SCbs_Type *_apfnI2SCbs[2] = { 00049 NULL, // I2S transmit Call-back function pointer 00050 NULL, // I2S receive Call-back function pointer 00051 }; 00052 00053 00054 /* Private Functions ---------------------------------------------------------- */ 00055 /** @defgroup I2S_Private_Functions 00056 * @{ 00057 */ 00058 00059 /********************************************************************//** 00060 * @brief Get I2S wordwidth value 00061 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00062 * @param[in] TRMode is the I2S mode, should be: 00063 * - I2S_TX_MODE: transmit mode 00064 * - I2S_RX_MODE: receive mode 00065 * @return The wordwidth value, should be: 8,16 or 32 00066 *********************************************************************/ 00067 uint8_t I2S_GetWordWidth(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { 00068 uint8_t value; 00069 00070 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00071 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00072 00073 if (TRMode == I2S_TX_MODE) { 00074 value = (I2Sx->I2SDAO) & 0x03; /* get wordwidth bit */ 00075 } else { 00076 value = (I2Sx->I2SDAI) & 0x03; /* get wordwidth bit */ 00077 } 00078 switch (value) { 00079 case I2S_WORDWIDTH_8: 00080 return 8; 00081 case I2S_WORDWIDTH_16: 00082 return 16; 00083 default: 00084 return 32; 00085 } 00086 } 00087 /********************************************************************//** 00088 * @brief Get I2S channel value 00089 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00090 * @param[in] TRMode is the I2S mode, should be: 00091 * - I2S_TX_MODE: transmit mode 00092 * - I2S_RX_MODE: receive mode 00093 * @return The channel value, should be: 1(mono) or 2(stereo) 00094 *********************************************************************/ 00095 uint8_t I2S_GetChannel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { 00096 uint8_t value; 00097 00098 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00099 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00100 00101 if (TRMode == I2S_TX_MODE) { 00102 value = (I2Sx->I2SDAO) & 0x04; /* get bit[2] */ 00103 } else { 00104 value = (I2Sx->I2SDAI) & 0x04; /* get bit[2] */ 00105 } 00106 switch (value) { 00107 case I2S_MONO: 00108 return 1; 00109 default: 00110 return 2; 00111 } 00112 } 00113 00114 /** 00115 * @} 00116 */ 00117 00118 00119 /* Public Functions ----------------------------------------------------------- */ 00120 /** @addtogroup I2S_Public_Functions 00121 * @{ 00122 */ 00123 00124 /********************************************************************//** 00125 * @brief Initialize I2S 00126 * - Turn on power and clock 00127 * - Setup I2S pin select 00128 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00129 * @return none 00130 *********************************************************************/ 00131 void I2S_Init(LPC_I2S_TypeDef *I2Sx) { 00132 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00133 00134 // Turn on power and clock 00135 CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, ENABLE); 00136 LPC_I2S->I2SDAI = LPC_I2S->I2SDAO = 0x00; 00137 } 00138 00139 /********************************************************************//** 00140 * @brief Configuration I2S, setting: 00141 * - master/slave mode 00142 * - wordwidth value 00143 * - channel mode 00144 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00145 * @param[in] TRMode: transmit/receive mode, should be: 00146 * - I2S_TX_MODE: transmit mode 00147 * - I2S_RX_MODE: receive mode 00148 * @param[in] ConfigStruct pointer to I2S_CFG_Type structure 00149 * which will be initialized. 00150 * @return none 00151 *********************************************************************/ 00152 void I2S_Config(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, I2S_CFG_Type* ConfigStruct) 00153 { 00154 uint32_t bps, config; 00155 00156 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00157 00158 CHECK_PARAM(PARAM_I2S_WORDWIDTH(ConfigStruct->wordwidth)); 00159 CHECK_PARAM(PARAM_I2S_CHANNEL(ConfigStruct->mono)); 00160 CHECK_PARAM(PARAM_I2S_STOP(ConfigStruct->stop)); 00161 CHECK_PARAM(PARAM_I2S_RESET(ConfigStruct->reset)); 00162 CHECK_PARAM(PARAM_I2S_WS_SEL(ConfigStruct->ws_sel)); 00163 CHECK_PARAM(PARAM_I2S_MUTE(ConfigStruct->mute)); 00164 00165 /* Setup clock */ 00166 bps = (ConfigStruct->wordwidth +1)*8; 00167 00168 /* Calculate audio config */ 00169 config = (bps - 1)<<6 | (ConfigStruct->ws_sel)<<5 | (ConfigStruct->reset)<<4 | 00170 (ConfigStruct->stop)<<3 | (ConfigStruct->mono)<<2 | (ConfigStruct->wordwidth); 00171 00172 if(TRMode == I2S_RX_MODE){ 00173 LPC_I2S->I2SDAI = config; 00174 }else{ 00175 LPC_I2S->I2SDAO = config; 00176 } 00177 } 00178 00179 /********************************************************************//** 00180 * @brief DeInitial both I2S transmit or receive 00181 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00182 * @return none 00183 *********************************************************************/ 00184 void I2S_DeInit(LPC_I2S_TypeDef *I2Sx) { 00185 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00186 00187 // Turn off power and clock 00188 CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCI2S, DISABLE); 00189 } 00190 00191 /********************************************************************//** 00192 * @brief Get I2S Buffer Level 00193 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00194 * @param[in] TRMode: Transmit/receive mode, should be: 00195 * - I2S_TX_MODE: transmit mode 00196 * - I2S_RX_MODE: receive mode 00197 * @return current level of Transmit/Receive Buffer 00198 *********************************************************************/ 00199 uint8_t I2S_GetLevel(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) 00200 { 00201 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00202 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00203 00204 if(TRMode == I2S_TX_MODE) 00205 { 00206 return ((I2Sx->I2SSTATE >> 16) & 0xFF); 00207 } 00208 else 00209 { 00210 return ((I2Sx->I2SSTATE >> 8) & 0xFF); 00211 } 00212 } 00213 /********************************************************************//** 00214 * @brief I2S Start: clear all STOP,RESET and MUTE bit, ready to operate 00215 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00216 * @return none 00217 *********************************************************************/ 00218 void I2S_Start(LPC_I2S_TypeDef *I2Sx) 00219 { 00220 //Clear STOP,RESET and MUTE bit 00221 I2Sx->I2SDAO &= ~I2S_DAI_RESET; 00222 I2Sx->I2SDAI &= ~I2S_DAI_RESET; 00223 I2Sx->I2SDAO &= ~I2S_DAI_STOP; 00224 I2Sx->I2SDAI &= ~I2S_DAI_STOP; 00225 I2Sx->I2SDAO &= ~I2S_DAI_MUTE; 00226 } 00227 /********************************************************************//** 00228 * @brief I2S Send data 00229 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00230 * @param[in] BufferData pointer to uint32_t is the data will be send 00231 * @return none 00232 *********************************************************************/ 00233 void I2S_Send(LPC_I2S_TypeDef *I2Sx, uint32_t BufferData) { 00234 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00235 CHECK_PARAM(PARAM_I2S_DATA(BufferData)); 00236 00237 I2Sx->I2STXFIFO = BufferData; 00238 } 00239 00240 /********************************************************************//** 00241 * @brief I2S Receive Data 00242 * @param[in] I2Sx pointer to LPC_I2S_TypeDef 00243 * @return received value 00244 *********************************************************************/ 00245 uint32_t I2S_Receive(LPC_I2S_TypeDef* I2Sx) { 00246 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00247 00248 return (I2Sx->I2SRXFIFO); 00249 00250 } 00251 /********************************************************************//** 00252 * @brief I2S Pause 00253 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00254 * @param[in] TRMode is transmit/receive mode, should be: 00255 * - I2S_TX_MODE: transmit mode 00256 * - I2S_RX_MODE: receive mode 00257 * @return none 00258 *********************************************************************/ 00259 void I2S_Pause(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { 00260 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00261 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00262 00263 if (TRMode == I2S_TX_MODE) //Transmit mode 00264 { 00265 I2Sx->I2SDAO |= I2S_DAO_STOP; 00266 } else //Receive mode 00267 { 00268 I2Sx->I2SDAI |= I2S_DAI_STOP; 00269 } 00270 } 00271 /********************************************************************//** 00272 * @brief I2S Mute 00273 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00274 * @param[in] TRMode is transmit/receive mode, should be: 00275 * - I2S_TX_MODE: transmit mode 00276 * - I2S_RX_MODE: receive mode 00277 * @return none 00278 *********************************************************************/ 00279 void I2S_Mute(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { 00280 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00281 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00282 00283 if (TRMode == I2S_TX_MODE) //Transmit mode 00284 { 00285 I2Sx->I2SDAO |= I2S_DAO_MUTE; 00286 } else //Receive mode 00287 { 00288 I2Sx->I2SDAI |= I2S_DAI_MUTE; 00289 } 00290 } 00291 00292 /********************************************************************//** 00293 * @brief I2S Stop 00294 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00295 * @param[in] TRMode is transmit/receive mode, should be: 00296 * - I2S_TX_MODE: transmit mode 00297 * - I2S_RX_MODE: receive mode 00298 * @return none 00299 *********************************************************************/ 00300 void I2S_Stop(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode) { 00301 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00302 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00303 00304 if (TRMode == I2S_TX_MODE) //Transmit mode 00305 { 00306 I2Sx->I2SDAO &= ~I2S_DAO_MUTE; 00307 I2Sx->I2SDAO |= I2S_DAO_STOP; 00308 I2Sx->I2SDAO |= I2S_DAO_RESET; 00309 } else //Receive mode 00310 { 00311 I2Sx->I2SDAI |= I2S_DAI_STOP; 00312 I2Sx->I2SDAI |= I2S_DAI_RESET; 00313 } 00314 } 00315 00316 /********************************************************************//** 00317 * @brief Set frequency for I2S 00318 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00319 * @param[in] Freq is the frequency for I2S will be set. It can range 00320 * from 16-96 kHz(16, 22.05, 32, 44.1, 48, 96kHz) 00321 * @param[in] TRMode is transmit/receive mode, should be: 00322 * - I2S_TX_MODE: transmit mode 00323 * - I2S_RX_MODE: receive mode 00324 * @return Status: ERROR or SUCCESS 00325 *********************************************************************/ 00326 Status I2S_FreqConfig(LPC_I2S_TypeDef *I2Sx, uint32_t Freq, uint8_t TRMode) { 00327 00328 /* Calculate bit rate 00329 * The formula is: 00330 * bit_rate = channel*wordwidth - 1 00331 * 48kHz sample rate for 16 bit stereo date requires 00332 * a bit rate of 48000*16*2=1536MHz (MCLK) 00333 */ 00334 uint32_t i2sPclk; 00335 uint64_t divider; 00336 uint8_t bitrate, channel, wordwidth; 00337 uint32_t x, y; 00338 uint16_t dif; 00339 uint16_t error; 00340 uint8_t x_divide, y_divide=0; 00341 uint16_t ErrorOptimal = 0xFFFF; 00342 00343 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00344 CHECK_PARAM(PRAM_I2S_FREQ(Freq)); 00345 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00346 00347 i2sPclk = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_I2S); 00348 if(TRMode == I2S_TX_MODE) 00349 { 00350 channel = I2S_GetChannel(I2Sx,I2S_TX_MODE); 00351 wordwidth = I2S_GetWordWidth(I2Sx,I2S_TX_MODE); 00352 } 00353 else 00354 { 00355 channel = I2S_GetChannel(I2Sx,I2S_RX_MODE); 00356 wordwidth = I2S_GetWordWidth(I2Sx,I2S_RX_MODE); 00357 } 00358 bitrate = channel * wordwidth - 1; 00359 if (TRMode == I2S_TX_MODE)// Transmitter 00360 { 00361 I2Sx->I2STXBITRATE = bitrate; 00362 } else //Receiver 00363 { 00364 I2Sx->I2SRXBITRATE = bitrate; 00365 } 00366 /* Calculate X and Y divider 00367 * The MCLK rate for the I2S transmitter is determined by the value 00368 * in the I2STXRATE/I2SRXRATE register. The required I2STXRATE/I2SRXRATE 00369 * setting depends on the desired audio sample rate desired, the format 00370 * (stereo/mono) used, and the data size. 00371 * The formula is: 00372 * I2S_MCLK = PCLK * (X/Y) / 2 00373 * We have: 00374 * I2S_MCLK = Freq * bit_rate; 00375 * So: (X/Y) = (Freq * bit_rate)/PCLK*2 00376 * We use a loop function to chose the most suitable X,Y value 00377 */ 00378 00379 divider = ((uint64_t)(Freq *( bitrate+1)* 2)<<16) / i2sPclk; 00380 for (y = 255; y > 0; y--) { 00381 x = y * divider; 00382 dif = x & 0xFFFF; 00383 if(dif>0x8000) error = 0x10000-dif; 00384 else error = dif; 00385 if (error == 0) 00386 { 00387 y_divide = y; 00388 break; 00389 } 00390 else if (error < ErrorOptimal) 00391 { 00392 ErrorOptimal = error; 00393 y_divide = y; 00394 } 00395 } 00396 x_divide = (y_divide * Freq *( bitrate+1)* 2)/i2sPclk; 00397 if (TRMode == I2S_TX_MODE)// Transmitter 00398 { 00399 I2Sx->I2STXRATE = y_divide | (x_divide << 8); 00400 } else //Receiver 00401 { 00402 I2Sx->I2SRXRATE = y_divide | (x_divide << 8); 00403 } 00404 return SUCCESS; 00405 } 00406 /********************************************************************//** 00407 * @brief I2S set bitrate 00408 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00409 * @param[in] bitrate value will be set 00410 * @param[in] TRMode is transmit/receive mode, should be: 00411 * - I2S_TX_MODE: transmit mode 00412 * - I2S_RX_MODE: receive mode 00413 * @return none 00414 *********************************************************************/ 00415 void I2S_SetBitRate(LPC_I2S_TypeDef *I2Sx, uint8_t bitrate, uint8_t TRMode) 00416 { 00417 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00418 CHECK_PARAM(PARAM_I2S_BITRATE(bitrate)); 00419 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00420 00421 if(TRMode == I2S_TX_MODE) 00422 { 00423 I2Sx->I2STXBITRATE = (bitrate -1); 00424 } 00425 else 00426 { 00427 I2Sx->I2SRXBITRATE = (bitrate -1); 00428 } 00429 } 00430 /********************************************************************//** 00431 * @brief Configuration operating mode for I2S 00432 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00433 * @param[in] ModeConfig pointer to I2S_MODEConf_Type will be used to 00434 * configure, should be: 00435 * @param[in] TRMode is transmit/receive mode, should be: 00436 * - I2S_TX_MODE: transmit mode 00437 * - I2S_RX_MODE: receive mode 00438 * @return none 00439 *********************************************************************/ 00440 void I2S_ModeConfig(LPC_I2S_TypeDef *I2Sx, I2S_MODEConf_Type* ModeConfig, 00441 uint8_t TRMode) 00442 { 00443 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00444 CHECK_PARAM(PARAM_I2S_CLKSEL(ModeConfig->clksel)); 00445 CHECK_PARAM(PARAM_I2S_4PIN(ModeConfig->fpin)); 00446 CHECK_PARAM(PARAM_I2S_MCLK(ModeConfig->mcena)); 00447 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00448 00449 if (TRMode == I2S_TX_MODE) { 00450 I2Sx->I2STXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register 00451 if (ModeConfig->clksel == I2S_CLKSEL_1) { 00452 I2Sx->I2STXMODE |= 0x02; 00453 } 00454 if (ModeConfig->fpin == I2S_4PIN_ENABLE) { 00455 I2Sx->I2STXMODE |= (1 << 2); 00456 } 00457 if (ModeConfig->mcena == I2S_MCLK_ENABLE) { 00458 I2Sx->I2STXMODE |= (1 << 3); 00459 } 00460 } else { 00461 I2Sx->I2SRXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register 00462 if (ModeConfig->clksel == I2S_CLKSEL_1) { 00463 I2Sx->I2SRXMODE |= 0x02; 00464 } 00465 if (ModeConfig->fpin == I2S_4PIN_ENABLE) { 00466 I2Sx->I2SRXMODE |= (1 << 2); 00467 } 00468 if (ModeConfig->mcena == I2S_MCLK_ENABLE) { 00469 I2Sx->I2SRXMODE |= (1 << 3); 00470 } 00471 } 00472 } 00473 00474 /********************************************************************//** 00475 * @brief Configure DMA operation for I2S 00476 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00477 * @param[in] DMAConfig pointer to I2S_DMAConf_Type will be used to configure 00478 * @param[in] TRMode is transmit/receive mode, should be: 00479 * - I2S_TX_MODE: transmit mode 00480 * - I2S_RX_MODE: receive mode 00481 * @return none 00482 *********************************************************************/ 00483 void I2S_DMAConfig(LPC_I2S_TypeDef *I2Sx, I2S_DMAConf_Type* DMAConfig, 00484 uint8_t TRMode) 00485 { 00486 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00487 CHECK_PARAM(PARAM_I2S_DMA(DMAConfig->DMAIndex)); 00488 CHECK_PARAM(PARAM_I2S_DMA_DEPTH(DMAConfig->depth)); 00489 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00490 00491 if (TRMode == I2S_RX_MODE) { 00492 if (DMAConfig->DMAIndex == I2S_DMA_1) { 00493 LPC_I2S->I2SDMA1 = (DMAConfig->depth) << 8; 00494 } else { 00495 LPC_I2S->I2SDMA2 = (DMAConfig->depth) << 8; 00496 } 00497 } else { 00498 if (DMAConfig->DMAIndex == I2S_DMA_1) { 00499 LPC_I2S->I2SDMA1 = (DMAConfig->depth) << 16; 00500 } else { 00501 LPC_I2S->I2SDMA2 = (DMAConfig->depth) << 16; 00502 } 00503 } 00504 } 00505 00506 /********************************************************************//** 00507 * @brief Enable/Disable DMA operation for I2S 00508 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00509 * @param[in] DMAIndex chose what DMA is used, should be: 00510 * - I2S_DMA_1: DMA1 00511 * - I2S_DMA_2: DMA2 00512 * @param[in] TRMode is transmit/receive mode, should be: 00513 * - I2S_TX_MODE: transmit mode 00514 * - I2S_RX_MODE: receive mode 00515 * @param[in] NewState is new state of DMA operation, should be: 00516 * - ENABLE 00517 * - DISABLE 00518 * @return none 00519 *********************************************************************/ 00520 void I2S_DMACmd(LPC_I2S_TypeDef *I2Sx, uint8_t DMAIndex, uint8_t TRMode, 00521 FunctionalState NewState) 00522 { 00523 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00524 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 00525 CHECK_PARAM(PARAM_I2S_DMA(DMAIndex)); 00526 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00527 00528 if (TRMode == I2S_RX_MODE) { 00529 if (DMAIndex == I2S_DMA_1) { 00530 if (NewState == ENABLE) 00531 I2Sx->I2SDMA1 |= 0x01; 00532 else 00533 I2Sx->I2SDMA1 &= ~0x01; 00534 } else { 00535 if (NewState == ENABLE) 00536 I2Sx->I2SDMA2 |= 0x01; 00537 else 00538 I2Sx->I2SDMA2 &= ~0x01; 00539 } 00540 } else { 00541 if (DMAIndex == I2S_DMA_1) { 00542 if (NewState == ENABLE) 00543 I2Sx->I2SDMA1 |= 0x02; 00544 else 00545 I2Sx->I2SDMA1 &= ~0x02; 00546 } else { 00547 if (NewState == ENABLE) 00548 I2Sx->I2SDMA2 |= 0x02; 00549 else 00550 I2Sx->I2SDMA2 &= ~0x02; 00551 } 00552 } 00553 } 00554 00555 /********************************************************************//** 00556 * @brief Configure IRQ for I2S 00557 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00558 * @param[in] TRMode is transmit/receive mode, should be: 00559 * - I2S_TX_MODE: transmit mode 00560 * - I2S_RX_MODE: receive mode 00561 * @param[in] level: is the FIFO level that triggers IRQ request 00562 * @param[in] pfnI2SCbs: the pointer to call-back function handle this interrupt 00563 * @return none 00564 *********************************************************************/ 00565 void I2S_IRQConfig(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, uint8_t level, fnI2SCbs_Type *pfnI2SCbs) { 00566 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00567 CHECK_PARAM(PARAM_I2S_TRX(TRMode)); 00568 CHECK_PARAM(PARAM_I2S_IRQ_LEVEL(level)); 00569 00570 if (TRMode == I2S_RX_MODE) { 00571 I2Sx->I2SIRQ |= (level << 8); 00572 } else { 00573 I2Sx->I2SIRQ |= (level << 16); 00574 } 00575 //setup Call-Back funtion for receive interrupt 00576 _apfnI2SCbs[TRMode] = pfnI2SCbs; 00577 } 00578 00579 /********************************************************************//** 00580 * @brief Enable/Disable IRQ for I2S 00581 * @param[in] I2Sx: I2S peripheral selected, should be: I2S 00582 * @param[in] TRMode is transmit/receive mode, should be: 00583 * - I2S_TX_MODE: transmit mode 00584 * - I2S_RX_MODE: receive mode 00585 * @param[in] NewState is new state of DMA operation, should be: 00586 * - ENABLE 00587 * - DISABLE 00588 * @return none 00589 *********************************************************************/ 00590 void I2S_IRQCmd(LPC_I2S_TypeDef *I2Sx, uint8_t TRMode, FunctionalState NewState) { 00591 CHECK_PARAM(PARAM_I2Sx(I2Sx)); 00592 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 00593 00594 if (TRMode == I2S_RX_MODE) { 00595 if (NewState == ENABLE) 00596 I2Sx->I2SIRQ |= 0x01; 00597 else 00598 I2Sx->I2SIRQ &= ~0x01; 00599 //Enable DMA 00600 00601 } else { 00602 if (NewState == ENABLE) 00603 I2Sx->I2SIRQ |= 0x02; 00604 else 00605 I2Sx->I2SIRQ &= ~0x02; 00606 } 00607 } 00608 /*********************************************************************//** 00609 * @brief Standard I2S interrupt handler, this function will check 00610 * all interrupt status of I2S channels, then execute the call 00611 * back function if they're already installed 00612 * @param[in] None 00613 * @return None 00614 **********************************************************************/ 00615 void I2S_IntHandler(void) 00616 { 00617 uint8_t rx_level, 00618 tx_level, 00619 tx_depth_irq, 00620 rx_depth_irq; 00621 00622 00623 if((LPC_I2S->I2SIRQ)& 0x01){ //receive interrupt 00624 rx_level = ((LPC_I2S->I2SSTATE)>>8)&0xFF; 00625 rx_depth_irq = ((LPC_I2S->I2SIRQ)>>8)&0xFF; 00626 00627 if (rx_level >= rx_depth_irq)//receive interrupt 00628 { 00629 _apfnI2SCbs[1](); 00630 } 00631 } 00632 else if(((LPC_I2S->I2SIRQ)>>1)& 0x01) 00633 { 00634 tx_level = ((LPC_I2S->I2SSTATE)>>16)&0xFF; 00635 tx_depth_irq = ((LPC_I2S->I2SIRQ)>>16)&0xFF; 00636 if(tx_level <= tx_depth_irq)//transmit interrupt 00637 { 00638 _apfnI2SCbs[0](); 00639 } 00640 } 00641 } 00642 00643 /** 00644 * @} 00645 */ 00646 00647 #endif /* _I2S */ 00648 00649 #ifdef __cplusplus 00650 } 00651 #endif 00652 00653 /** 00654 * @} 00655 */ 00656 00657 /* --------------------------------- End Of File ------------------------------ */ 00658
Generated on Tue Jul 12 2022 17:06:02 by 1.7.2