CC26xx Driver Library |

- Main Page
- Related Pages
- CC26xx APIs
- Register Descriptions
- Online Resources

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
i2s.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: i2s.c
3 * Revised: 2015-01-13 16:59:55 +0100 (ti, 13 jan 2015)
4 * Revision: 42365
5 *
6 * Description: Driver for the I2S.
7 *
8 * Copyright (c) 2015, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 #include <driverlib/i2s.h>
40
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #ifndef DRIVERLIB_GENERATE_ROM
48 #undef I2SEnable
49 #define I2SEnable NOROM_I2SEnable
50 #undef I2SAudioFormatConfigure
51 #define I2SAudioFormatConfigure NOROM_I2SAudioFormatConfigure
52 #undef I2SChannelConfigure
53 #define I2SChannelConfigure NOROM_I2SChannelConfigure
54 #undef I2SBufferConfig
55 #define I2SBufferConfig NOROM_I2SBufferConfig
56 #undef I2SPointerUpdate
57 #define I2SPointerUpdate NOROM_I2SPointerUpdate
58 #undef I2SPointerSet
59 #define I2SPointerSet NOROM_I2SPointerSet
60 #undef I2SSampleStampConfigure
61 #define I2SSampleStampConfigure NOROM_I2SSampleStampConfigure
62 #undef I2SSampleStampGet
63 #define I2SSampleStampGet NOROM_I2SSampleStampGet
64 #endif
65
66 //*****************************************************************************
67 //
68 // Global pointer to the current I2S data structure
69 //
70 //*****************************************************************************
71 I2SControlTable *g_pControlTable;
72
73 //*****************************************************************************
74 //
76 //
77 //*****************************************************************************
78 void
79 I2SEnable(uint32_t ui32Base)
80 {
81 //
82 // Check the arguments.
83 //
84 ASSERT(I2SBaseValid(ui32Base));
85
86 //
87 // Make sure the controltable pointer is setup to a memory location.
88 //
89 if(!(g_pControlTable))
90 {
91 return;
92 }
93
94 //
95 // Write the address to the first input/output buffer.
96 //
97 HWREG(I2S0_BASE + I2S_O_AIFINPTRNEXT) = g_pControlTable->ui32InBase;
98 g_pControlTable->ui32InOffset = 0;
99 HWREG(I2S0_BASE + I2S_O_AIFOUTPTRNEXT) = g_pControlTable->ui32OutBase;
100 g_pControlTable->ui32OutOffset = 0;
101
102 //
103 // Enable the I2S module.
104 //
105 HWREG(ui32Base + I2S_O_AIFDMACFG) = (uint32_t)g_pControlTable->ui16DMABufSize - 1;
106 }
107
108 //*****************************************************************************
109 //
111 //
112 //*****************************************************************************
113 void
114 I2SAudioFormatConfigure(uint32_t ui32Base, uint32_t ui32FmtCfg,
115 uint32_t ui32BitClkDelay)
116 {
117 //
118 // Check the arguments.
119 //
120 ASSERT(I2SBaseValid(ui32Base));
121 ASSERT(ui32BitClkDelay <= 255);
122
123 //
124 // Save the length of the audio words stored in memory.
125 //
126 g_pControlTable->ui16MemLen = (ui32FmtCfg & I2S_MEM_LENGTH_24) ? 24 : 16;
127
128 //
129 // Write the configuration.
130 //
131 HWREG(ui32Base + I2S_O_AIFFMTCFG) = ui32FmtCfg | (ui32BitClkDelay << I2S_AIFFMTCFG_DATA_DELAY_S);
132 }
133
134 //****************************************************************************
135 //
137 //
138 //****************************************************************************
139 void
140 I2SChannelConfigure(uint32_t ui32Base, uint32_t ui32Chan0Cfg,
141 uint32_t ui32Chan1Cfg, uint32_t ui32Chan2Cfg)
142 {
143 uint32_t ui32InChan;
144 uint32_t ui32OutChan;
145 uint32_t ui32ChanMask;
146
147 //
148 // Check the arguments.
149 //
150 ASSERT(I2SBaseValid(ui32Base));
151 ASSERT(ui32Chan0Cfg & (I2S_CHAN_CFG_MASK | I2S_LINE_MASK))
152 ASSERT(ui32Chan1Cfg & (I2S_CHAN_CFG_MASK | I2S_LINE_MASK))
153 ASSERT(ui32Chan2Cfg & (I2S_CHAN_CFG_MASK | I2S_LINE_MASK))
154
155 ui32InChan = 0;
156 ui32OutChan = 0;
157
158 //
159 // Configure input/output channels.
160 //
161 HWREG(ui32Base + I2S_O_AIFDIRCFG) = ((ui32Chan0Cfg << I2S_AIFDIRCFG_AD0_S)
162 & I2S_AIFDIRCFG_AD0_M) |
163 ((ui32Chan1Cfg << I2S_AIFDIRCFG_AD1_S)
164 & I2S_AIFDIRCFG_AD1_M) |
165 ((ui32Chan2Cfg << I2S_AIFDIRCFG_AD2_S)
166 & I2S_AIFDIRCFG_AD2_M);
167
168 //
169 // Configure the valid channel mask.
170 //
171 HWREG(ui32Base + I2S_O_AIFWMASK0) = (ui32Chan0Cfg >> 8) & I2S_AIFWMASK0_MASK_M;
172 HWREG(ui32Base + I2S_O_AIFWMASK1) = (ui32Chan1Cfg >> 8) & I2S_AIFWMASK1_MASK_M;
173 HWREG(ui32Base + I2S_O_AIFWMASK2) = (ui32Chan2Cfg >> 8) & I2S_AIFWMASK2_MASK_M;
174
175 //
176 // Resolve and save the number of input and output channels.
177 //
178 ui32ChanMask = (ui32Chan0Cfg & I2S_CHAN_CFG_MASK) >> 8;
179 if(ui32Chan0Cfg & I2S_LINE_INPUT)
180 {
181 while(ui32ChanMask)
182 {
183 if(ui32ChanMask & 0x1)
184 {
185 ui32InChan++;
186 }
187 //
188 // Shift down channel mask
189 //
190 ui32ChanMask >>= 1;
191 }
192
193 }
194 else if(ui32Chan0Cfg & I2S_LINE_OUTPUT)
195 {
196 while(ui32ChanMask)
197 {
198 if(ui32ChanMask & 0x1)
199 {
200 ui32OutChan++;
201 }
202 //
203 // Shift down channel mask
204 //
205 ui32ChanMask >>= 1;
206 }
207 }
208
209 ui32ChanMask = (ui32Chan1Cfg & I2S_CHAN_CFG_MASK) >> 8;
210 if(ui32Chan1Cfg & I2S_LINE_INPUT)
211 {
212 while(ui32ChanMask)
213 {
214 if(ui32ChanMask & 0x1)
215 {
216 ui32InChan++;
217 }
218 //
219 // Shift down channel mask
220 //
221 ui32ChanMask >>= 1;
222 }
223 }
224 else if(ui32Chan1Cfg & I2S_LINE_OUTPUT)
225 {
226 while(ui32ChanMask)
227 {
228 if(ui32ChanMask & 0x1)
229 {
230 ui32OutChan++;
231 }
232 //
233 // Shift down channel mask
234 //
235 ui32ChanMask >>= 1;
236 }
237 }
238
239 ui32ChanMask = (ui32Chan2Cfg & I2S_CHAN_CFG_MASK) >> 8;
240 if(ui32Chan2Cfg & I2S_LINE_INPUT)
241 {
242 while(ui32ChanMask)
243 {
244 if(ui32ChanMask & 0x1)
245 {
246 ui32InChan++;
247 }
248 //
249 // Shift down channel mask
250 //
251 ui32ChanMask >>= 1;
252 }
253 }
254 else if(ui32Chan2Cfg & I2S_LINE_OUTPUT)
255 {
256 while(ui32ChanMask)
257 {
258 if(ui32ChanMask & 0x1)
259 {
260 ui32OutChan++;
261 }
262 //
263 // Shift down channel mask
264 //
265 ui32ChanMask >>= 1;
266 }
267 }
268
269 g_pControlTable->ui8InChan = (uint8_t)ui32InChan;
270 g_pControlTable->ui8OutChan = (uint8_t)ui32OutChan;
271 }
272
273 //****************************************************************************
274 //
276 //
277 //****************************************************************************
278 void
279 I2SBufferConfig(uint32_t ui32Base, uint32_t ui32InBufBase,
280 uint32_t ui32OutBufBase, uint16_t ui16DMABufSize,
281 uint16_t ui16ChanBufSize)
282 {
283 //
284 // Check the arguments.
285 //
286 ASSERT(I2SBaseValid(ui32Base));
287 ASSERT(ui16DMABufSize > 0);
288
289 //
290 // Setup the input data pointer and buffer sizes.
291 //
292 g_pControlTable->ui16DMABufSize = ui16DMABufSize;
293 g_pControlTable->ui16ChBufSize = ui16ChanBufSize;
294 g_pControlTable->ui32InBase = ui32InBufBase;
295 g_pControlTable->ui32OutBase = ui32OutBufBase;
296 }
297
298 //****************************************************************************
299 //
301 //
302 //****************************************************************************
303 void
304 I2SPointerSet(uint32_t ui32Base, bool bInput, void * pNextPointer)
305 {
306 //
307 // Check the arguments.
308 //
309 ASSERT(I2SBaseValid(ui32Base));
310
311 //
312 // Update the next input/output pointer with the correct address.
313 //
314 if(bInput == true)
315 {
316 HWREG(ui32Base + I2S_O_AIFINPTRNEXT) = (uint32_t)pNextPointer;
317 }
318 else
319 {
320 HWREG(ui32Base + I2S_O_AIFOUTPTRNEXT) = (uint32_t)pNextPointer;
321 }
322 }
323
324 //****************************************************************************
325 //
327 //
328 //****************************************************************************
329 void
330 I2SPointerUpdate(uint32_t ui32Base, bool bInput)
331 {
332 uint32_t ui32NextPtr;
333
334 //
335 // Check the arguments.
336 //
337 ASSERT(I2SBaseValid(ui32Base));
338
339 //
340 // Update the next input/output pointer with the correct address.
341 //
342 if(bInput == true)
343 {
344 ui32NextPtr = (g_pControlTable->ui8InChan *
345 (g_pControlTable->ui16MemLen >> 3)) *
346 g_pControlTable->ui16DMABufSize;
347 g_pControlTable->ui32InOffset = ((g_pControlTable->ui32InOffset +
348 ui32NextPtr) %
349 g_pControlTable->ui16ChBufSize);
350 HWREG(ui32Base + I2S_O_AIFINPTRNEXT) = g_pControlTable->ui32InOffset +
351 g_pControlTable->ui32InBase;
352 }
353 else
354 {
355 ui32NextPtr = (g_pControlTable->ui8OutChan *
356 (g_pControlTable->ui16MemLen >> 3)) *
357 g_pControlTable->ui16DMABufSize;
358 g_pControlTable->ui32OutOffset = ((g_pControlTable->ui32OutOffset +
359 ui32NextPtr) %
360 g_pControlTable->ui16ChBufSize);
361 HWREG(ui32Base + I2S_O_AIFOUTPTRNEXT) =
362 g_pControlTable->ui32OutOffset +
363 g_pControlTable->ui32OutBase;
364 }
365 }
366
367 //*****************************************************************************
368 //
370 //
371 //*****************************************************************************
372 void
373 I2SSampleStampConfigure(uint32_t ui32Base, bool bInput, bool bOutput)
374 {
375 uint32_t ui32Trigger;
376
377 //
378 // Check the arguments.
379 //
380 ASSERT(I2SBaseValid(ui32Base));
381
382 ui32Trigger = HWREG(I2S0_BASE + I2S_O_STMPWCNT);
383 ui32Trigger = (ui32Trigger + 2) % g_pControlTable->ui16ChBufSize;
384
385 //
386 // Setup the samplestamp trigger for input streams.
387 //
388 if(bInput)
389 {
390 HWREG(I2S0_BASE + I2S_O_STMPINTRIG) = ui32Trigger;
391 }
392
393 //
394 // Setup the samplestamp trigger for output streams.
395 //
396 if(bOutput)
397 {
398 HWREG(I2S0_BASE + I2S_O_STMPOUTTRIG) = ui32Trigger;
399 }
400
401 }
402
403 //*****************************************************************************
404 //
406 //
407 //*****************************************************************************
408 uint32_t
409 I2SSampleStampGet(uint32_t ui32Base, uint32_t ui32Channel)
410 {
411 uint32_t ui32FrameClkCnt;
412 uint32_t ui32SysClkCnt;
413 uint32_t ui32PeriodSysClkCnt;
414 uint32_t ui32SampleStamp;
415
416 //
417 // Get the number of Frame clock counts since last stamp.
418 //
419 ui32FrameClkCnt = HWREG(ui32Base + I2S_O_STMPWCNTCAPT0);
420
421 //
422 // Get the number of system clock ticks since last frame clock edge.
423 //
424 ui32SysClkCnt = HWREG(ui32Base + I2S_O_STMPXCNTCAPT0);
425
426 //
427 // Get the number system clock ticks in the last frame clock period.
428 //
429 ui32PeriodSysClkCnt = HWREG(ui32Base + I2S_O_STMPXPER);
430
431 //
432 // Calculate the sample stamp.
433 //
434 ui32SampleStamp = (ui32SysClkCnt << 16) / ui32PeriodSysClkCnt;
435 ui32SampleStamp = (ui32SampleStamp > I2S_STMP_SATURATION) ?
436 I2S_STMP_SATURATION : ui32SampleStamp;
437 ui32SampleStamp |= (ui32FrameClkCnt << 16);
438
439 return (ui32SampleStamp);
440 }
I2SSampleStampConfigure
void I2SSampleStampConfigure(uint32_t ui32Base, bool bInput, bool bOutput)
Configure the sample stamp generator.
Definition: i2s.c:373
I2SPointerSet
void I2SPointerSet(uint32_t ui32Base, bool bInput, void *pNextPointer)
Set the buffer pointers.
Definition: i2s.c:304
I2S_LINE_MASK
#define I2S_LINE_MASK
Definition: i2s.h:168
I2SBufferConfig
void I2SBufferConfig(uint32_t ui32Base, uint32_t ui32InBufBase, uint32_t ui32OutBufBase, uint16_t ui16DMABufSize, uint16_t ui16ChanBufSize)
Set the input buffer pointers.
Definition: i2s.c:279
I2S_CHAN_CFG_MASK
#define I2S_CHAN_CFG_MASK
Definition: i2s.h:185
I2S_LINE_INPUT
#define I2S_LINE_INPUT
Definition: i2s.h:166
ASSERT
#define ASSERT(expr)
Definition: debug.h:65
I2SControlTable::ui16DMABufSize
uint16_t ui16DMABufSize
Size of DMA buffer in number of samples.
Definition: i2s.h:117
I2S_MEM_LENGTH_24
#define I2S_MEM_LENGTH_24
Definition: i2s.h:193
I2SControlTable::ui32InOffset
uint32_t ui32InOffset
Value of the current input pointer offset.
Definition: i2s.h:123
I2SSampleStampGet
uint32_t I2SSampleStampGet(uint32_t ui32Base, uint32_t ui32Channel)
Get the current value of a sample stamp counter.
Definition: i2s.c:409
I2SControlTable::ui32OutOffset
uint32_t ui32OutOffset
Value of the current output pointer offset.
Definition: i2s.h:125
I2SControlTable::ui32OutBase
uint32_t ui32OutBase
Base address of the output buffer.
Definition: i2s.h:124
I2SPointerUpdate
void I2SPointerUpdate(uint32_t ui32Base, bool bInput)
Update the buffer pointers.
Definition: i2s.c:330
I2SControlTable::ui16MemLen
uint16_t ui16MemLen
Length of the audio words stored in memory.
Definition: i2s.h:121
I2SControlTable
A structure that defines an audio control table. Note: Memory for this structure must be initialized ...
Definition: i2s.h:115
I2SControlTable::ui8InChan
uint8_t ui8InChan
Input Channel.
Definition: i2s.h:119
i2s.h
I2SEnable
void I2SEnable(uint32_t ui32Base)
Enables the I2S module for operation.
Definition: i2s.c:79
I2SControlTable::ui32InBase
uint32_t ui32InBase
Base address of the input buffer.
Definition: i2s.h:122
I2SAudioFormatConfigure
void I2SAudioFormatConfigure(uint32_t ui32Base, uint32_t ui32FmtCfg, uint32_t ui32BitClkDelay)
Configures the I2S module.
Definition: i2s.c:114
I2SControlTable::ui8OutChan
uint8_t ui8OutChan
Output Channel.
Definition: i2s.h:120
I2S_LINE_OUTPUT
#define I2S_LINE_OUTPUT
Definition: i2s.h:167
I2S_STMP_SATURATION
#define I2S_STMP_SATURATION
Definition: i2s.h:209
I2SChannelConfigure
void I2SChannelConfigure(uint32_t ui32Base, uint32_t ui32Chan0Cfg, uint32_t ui32Chan1Cfg, uint32_t ui32Chan2Cfg)
Setup the audio channel configuration.
Definition: i2s.c:140
g_pControlTable
I2SControlTable * g_pControlTable
Definition: i2s.c:71
I2SControlTable::ui16ChBufSize
uint16_t ui16ChBufSize
Size of Channel buffer.
Definition: i2s.h:118