| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2s_17xx_40xx.c
Go to the documentation of this file.
1 /*
2 * @brief LPC17xx/40xx I2S driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include "chip.h"
33
34 /*****************************************************************************
35 * Private types/enumerations/variables
36 ****************************************************************************/
37
38 /*****************************************************************************
39 * Public types/enumerations/variables
40 ****************************************************************************/
41
42 /*****************************************************************************
43 * Private functions
44 ****************************************************************************/
45
46 /*****************************************************************************
47 * Public functions
48 ****************************************************************************/
49
50 /* Initialize the I2S interface */
51 void Chip_I2S_Init(LPC_I2S_T *pI2S)
52 {
53 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2S);
54 IP_I2S_Init(pI2S);
55 }
56
57 /* Shutdown I2S */
58 void Chip_I2S_DeInit(LPC_I2S_T *pI2S)
59 {
60 IP_I2S_DeInit(pI2S);
61 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_I2S);
62 }
63
64 /* Configure I2S for Audio Format input */
65 Status Chip_I2S_Config(LPC_I2S_T *pI2S, uint8_t TRMode, Chip_I2S_Audio_Format_T *audio_format)
66 {
67 uint32_t pClk;
68 uint32_t x, y;
69 uint64_t divider;
70 uint16_t dif;
71 uint16_t x_divide = 0, y_divide = 0;
72 uint32_t N;
73 uint16_t err, ErrorOptimal = 0xFFFF;
74
75 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2S);
76 #if defined(CHIP_LPC175X_6X)
77 pClk = Chip_Clock_GetPeripheralClockRate(SYSCTL_PCLK_I2S);
78 #else
79 pClk = Chip_Clock_GetPeripheralClockRate();
80 #endif
81
82 /* divider is a fixed point number with 16 fractional bits */
83 divider = (((uint64_t) (audio_format->SampleRate) * 2 * (audio_format->WordWidth) * 2) << 16) / pClk;
84 /* find N that make x/y <= 1 -> divider <= 2^16 */
85 for (N = 64; N > 0; N--) {
86 if ((divider * N) < (1 << 16)) {
87 break;
88 }
89 }
90 if (N == 0) {
91 return ERROR;
92 }
93 divider *= N;
94 for (y = 255; y > 0; y--) {
95 x = y * divider;
96 if (x & (0xFF000000)) {
97 continue;
98 }
99 dif = x & 0xFFFF;
100 if (dif > 0x8000) {
101 err = 0x10000 - dif;
102 }
103 else {
104 err = dif;
105 }
106 if (err == 0) {
107 y_divide = y;
108 break;
109 }
110 else if (err < ErrorOptimal) {
111 ErrorOptimal = err;
112 y_divide = y;
113 }
114 }
115 x_divide = ((uint64_t) y_divide * (audio_format->SampleRate) * 2 * (audio_format->WordWidth) * N * 2) / pClk;
116 if (x_divide >= 256) {
117 x_divide = 0xFF;
118 }
119 if (x_divide == 0) {
120 x_divide = 1;
121 }
122 if (audio_format->WordWidth <= 8) {
123 IP_I2S_SetWordWidth(pI2S, TRMode, I2S_WORDWIDTH_8);
124 }
125 else if (audio_format->WordWidth <= 16) {
126 IP_I2S_SetWordWidth(pI2S, TRMode, I2S_WORDWIDTH_16);
127 }
128 else {
129 IP_I2S_SetWordWidth(pI2S, TRMode, I2S_WORDWIDTH_32);
130 }
131 IP_I2S_SetMono(pI2S, TRMode, (audio_format->ChannelNumber) == 1 ? I2S_MONO : I2S_STEREO);
132 IP_I2S_SetMasterSlaveMode(pI2S, TRMode, I2S_MASTER_MODE);
133 IP_I2S_SetWS_Halfperiod(pI2S, TRMode, audio_format->WordWidth - 1);
134 IP_I2S_ModeConfig(pI2S, TRMode, I2S_TXMODE_CLKSEL(0), !I2S_TXMODE_4PIN_ENABLE, !I2S_TXMODE_MCENA);
135 IP_I2S_SetBitRate(pI2S, TRMode, N - 1);
136 IP_I2S_SetXYDivider(pI2S, TRMode, x_divide, y_divide);
137 return SUCCESS;
138 }
139
140 /* Enable/Disable Interrupt with a specific FIFO depth */
141 void Chip_I2S_Int_Cmd(LPC_I2S_T *pI2S, uint8_t TRMode, FunctionalState NewState, uint8_t FIFO_Depth)
142 {
143 IP_I2S_InterruptCmd(pI2S, TRMode, NewState);
144 IP_I2S_SetFIFODepthIRQ(pI2S, TRMode, FIFO_Depth);
145 }
146
147 /* Enable/Disable DMA with a specific FIFO depth */
148 void Chip_I2S_DMA_Cmd(LPC_I2S_T *pI2S,
149 uint8_t TRMode,
150 uint8_t DMANum,
151 FunctionalState NewState,
152 uint8_t FIFO_Depth)
153 {
154 IP_I2S_SetFIFODepthDMA(pI2S, TRMode, (IP_I2S_DMARequestNumber_T) DMANum, FIFO_Depth);
155 IP_I2S_DMACmd(pI2S, (IP_I2S_DMARequestNumber_T) DMANum, TRMode, NewState);
156 }