CC27xxDriverLibrary
i2s.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Filename: i2s.h
3  *
4  * Description: Prototypes and defines for the I2S API.
5  *
6  * Copyright (c) 2023-2024 Texas Instruments Incorporated
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1) Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  *
14  * 2) Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3) Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  ******************************************************************************/
35 
36 #ifndef __I2S_H__
37 #define __I2S_H__
38 
39 //****************************************************************************
40 //
45 //
46 //****************************************************************************
47 
48 //*****************************************************************************
49 //
50 // If building with a C++ compiler, make all of the definitions in this header
51 // have a C binding.
52 //
53 //*****************************************************************************
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 #include <stdbool.h>
59 #include <stdint.h>
60 #include "../inc/hw_types.h"
61 #include "../inc/hw_ints.h"
62 #include "../inc/hw_memmap.h"
63 #include "../inc/hw_i2s.h"
64 #include "debug.h"
65 #include "interrupt.h"
66 
67 //*****************************************************************************
68 //
69 // Defines for selecting data pin usage.
70 //
71 //*****************************************************************************
72 #define I2S_SD0_DIS I2S_AIFDIRCFG_AD0_DIS
73 #define I2S_SD0_IN I2S_AIFDIRCFG_AD0_IN
74 #define I2S_SD0_OUT I2S_AIFDIRCFG_AD0_OUT
75 #define I2S_SD1_DIS I2S_AIFDIRCFG_AD1_DIS
76 #define I2S_SD1_IN I2S_AIFDIRCFG_AD1_IN
77 #define I2S_SD1_OUT I2S_AIFDIRCFG_AD1_OUT
78 
79 //*****************************************************************************
80 //
81 // Defines for activating an audio channel.
82 //
83 //*****************************************************************************
84 #define I2S_CHAN0_MASK 0x00000001
85 #define I2S_CHAN1_MASK 0x00000002
86 #define I2S_CHAN2_MASK 0x00000004
87 #define I2S_CHAN3_MASK 0x00000008
88 #define I2S_CHAN4_MASK 0x00000010
89 #define I2S_CHAN5_MASK 0x00000020
90 #define I2S_CHAN6_MASK 0x00000040
91 #define I2S_CHAN7_MASK 0x00000080
92 
93 //*****************************************************************************
94 //
95 // Defines for the audio format configuration
96 //
97 //*****************************************************************************
98 #define I2S_MEM_LENGTH_16 I2S_FMTCFG_MEMLEN32_DIS
99 #define I2S_MEM_LENGTH_32 I2S_FMTCFG_MEMLEN32_EN
100 #define I2S_POS_EDGE I2S_FMTCFG_SMPLEDGE_POSEDGE
101 #define I2S_NEG_EDGE I2S_FMTCFG_SMPLEDGE_NEGEDGE
102 
103 //*****************************************************************************
104 //
105 // Defines for the sample stamp counters
106 //
107 //*****************************************************************************
108 #define I2S_STMP_SATURATION 0x0000FFFF
109 
110 //*****************************************************************************
111 //
112 // Defines for the interrupt
113 //
114 //*****************************************************************************
115 #define I2S_INT_XCNT_CAPTURE I2S_IRQFLAGS_XCNTCAPT
116 #define I2S_INT_DMA_IN I2S_IRQFLAGS_DMAIN
117 #define I2S_INT_DMA_OUT I2S_IRQFLAGS_DMAOUT
118 #define I2S_INT_TIMEOUT I2S_IRQFLAGS_WCLKTIMEOUT
119 #define I2S_INT_BUS_ERR I2S_IRQFLAGS_BUSERR
120 #define I2S_INT_WCLK_ERR I2S_IRQFLAGS_WCLKERR
121 #define I2S_INT_PTR_ERR I2S_IRQFLAGS_PTRERR
122 #define I2S_INT_ALL \
123  (I2S_INT_XCNT_CAPTURE | I2S_INT_DMA_IN | I2S_INT_DMA_OUT | I2S_INT_TIMEOUT | I2S_INT_BUS_ERR | I2S_INT_WCLK_ERR | \
124  I2S_INT_PTR_ERR)
125 
126 //*****************************************************************************
127 //
128 // API Functions and prototypes
129 //
130 //*****************************************************************************
131 
132 #ifdef DRIVERLIB_DEBUG
133 //*****************************************************************************
134 //
145 //
146 //*****************************************************************************
147 static bool I2SBaseValid(uint32_t base)
148 {
149  return (base == I2S_BASE);
150 }
151 #endif
152 
153 //*****************************************************************************
154 //
174 //
175 //*****************************************************************************
176 __STATIC_INLINE void I2SEnableInt(uint32_t base, uint32_t intFlags)
177 {
178  // Check the arguments
179  ASSERT(I2SBaseValid(base));
180 
181  // Enable the specified interrupts
182  HWREG(I2S_BASE + I2S_O_IRQMASK) |= intFlags;
183 }
184 
185 //*****************************************************************************
186 //
206 //
207 //*****************************************************************************
208 __STATIC_INLINE void I2SDisableInt(uint32_t base, uint32_t intFlags)
209 {
210  // Check the arguments
211  ASSERT(I2SBaseValid(base));
212 
213  // Disable the specified interrupts
214  HWREG(I2S_BASE + I2S_O_IRQMASK) &= ~intFlags;
215 }
216 
217 //*****************************************************************************
218 //
238 //
239 //*****************************************************************************
240 __STATIC_INLINE uint32_t I2SIntStatus(uint32_t base, bool masked)
241 {
242  uint32_t status;
243 
244  // Check the arguments
245  ASSERT(I2SBaseValid(base));
246 
247  // Read the raw status
248  status = HWREG(I2S_BASE + I2S_O_IRQFLAGS);
249 
250  // If the masked status is requested, mask the raw status with the interrupt
251  // mask.
252  if (masked)
253  {
254  status &= HWREG(I2S_BASE + I2S_O_IRQMASK);
255  }
256 
257  return status;
258 }
259 
260 //*****************************************************************************
261 //
281 //
282 //*****************************************************************************
283 __STATIC_INLINE void I2SClearInt(uint32_t base, uint32_t intFlags)
284 {
285  // Check the arguments
286  ASSERT(I2SBaseValid(base));
287 
288  // Clear the requested interrupt sources
289  HWREG(I2S_BASE + I2S_O_IRQCLR) = intFlags;
290 }
291 
292 //*****************************************************************************
293 //
308 //
309 //*****************************************************************************
311 {
312  // Check the arguments
313  ASSERT(I2SBaseValid(base));
314 
315  // Set the enable bit
316  HWREG(I2S_BASE + I2S_O_STMPCTL) = I2S_STMPCTL_STMPEN_EN;
317 }
318 
319 //*****************************************************************************
320 //
329 //
330 //*****************************************************************************
332 {
333  // Check the arguments
334  ASSERT(I2SBaseValid(base));
335 
336  // Clear the enable bit
337  HWREG(I2S_BASE + I2S_O_STMPCTL) = 0;
338 }
339 
340 //*****************************************************************************
341 //
348 //
349 //*****************************************************************************
350 extern uint32_t I2SGetSampleStamp(uint32_t base, uint32_t channel);
351 
352 //*****************************************************************************
353 //
372 //
373 //*****************************************************************************
374 __STATIC_INLINE void I2SStart(uint32_t base, uint16_t dmaLength)
375 {
376  // Check the arguments
377  ASSERT(I2SBaseValid(base));
378 
379  // Enable the I2S module, by writting a non-zero value to AIFDMACFG.
380  // AIFDMACFG expects the end frame index to be written, and the end index is
381  // one less than the length.
382  HWREG(I2S_BASE + I2S_O_DMACFG) = (dmaLength - 1) & I2S_DMACFG_ENDFRMIDX_M;
383 }
384 
385 //*****************************************************************************
386 //
406 //
407 //*****************************************************************************
408 __STATIC_INLINE void I2SStop(uint32_t base)
409 {
410  // Check the arguments
411  ASSERT(I2SBaseValid(base));
412 
413  // Disable the I2S module
414  HWREG(I2S_BASE + I2S_O_DMACFG) = 0x00;
415 }
416 
417 //*****************************************************************************
418 //
450 //
451 //*****************************************************************************
453  uint8_t dataDelay,
454  uint32_t memoryLength,
455  uint32_t samplingEdge,
456  bool dualPhase,
457  uint8_t bitsPerSample)
458 {
459  // Check the arguments
460  ASSERT(I2SBaseValid(base));
461  ASSERT(bitsPerSample <= 24); // Max. I2S_AIFFMTCFG_WORD_LEN
462  ASSERT(bitsPerSample >= 8); // Min. I2S_AIFFMTCFG_WORD_LEN
463 
464  // Setup register AIFFMTCFG Source
465  HWREGH(I2S_BASE + I2S_O_FMTCFG) = (dataDelay << I2S_FMTCFG_DATADLY_S) | (memoryLength) | (samplingEdge) |
466  (dualPhase << I2S_FMTCFG_DUALPHASE_S) | (bitsPerSample << I2S_FMTCFG_WORDLEN_S);
467 }
468 
469 //****************************************************************************
470 //
508 //
509 //****************************************************************************
511  uint8_t sd0Usage,
512  uint8_t sd0Channels,
513  uint8_t sd1Usage,
514  uint8_t sd1Channels)
515 {
516  // Check the arguments
517  ASSERT(I2SBaseValid(base));
518 
519  // Configure input/output channels
520  HWREGB(I2S_BASE + I2S_O_DIRCFG) = (sd0Usage | sd1Usage);
521 
522  // Configure the valid channel mask
523  HWREGB(I2S_BASE + I2S_O_WMASK0) = sd0Channels;
524  HWREGB(I2S_BASE + I2S_O_WMASK1) = sd1Channels;
525 }
526 
527 //****************************************************************************
528 //
572 //
573 //****************************************************************************
575  bool isController,
576  bool invertWclk,
577  bool dualPhase,
578  uint32_t cclkDiv,
579  uint32_t wclkDiv,
580  uint32_t bclkDiv)
581 {
582  // Check the arguments
583  ASSERT(I2SBaseValid(base));
584  ASSERT(cclkDiv <= 1024);
585  ASSERT(cclkDiv >= 2);
586  ASSERT(wclkDiv <= 1023);
587  ASSERT(wclkDiv >= 1);
588  ASSERT(bclkDiv <= 1024);
589  ASSERT(bclkDiv >= 2);
590 
591  // Setup register WCLK and BCLK Source
592  HWREGB(I2S_BASE + I2S_O_WCLKSRC) = ((isController ? I2S_WCLKSRC_WBCLKSRC_INT : I2S_WCLKSRC_WBCLKSRC_EXT) |
593  (invertWclk ? I2S_WCLKSRC_WCLKINV : 0));
594 
595  // Configure internal clocks, if internal clocks are to be used
596  if (isController)
597  {
598 
599  // Make sure to compensate the WCLK division factor if using single
600  // phase format.
601  if (dualPhase == false)
602  {
603  wclkDiv -= 1;
604  }
605 
606  // Write the clock division factors.
607  // A value of 0 is interpreted as 1024 for CCLK and BCLK.
608  HWREG(I2S_BASE + I2S_O_MCLKDIV) = (cclkDiv == 1024 ? 0 : cclkDiv);
609  HWREG(I2S_BASE + I2S_O_WCLKDIV) = wclkDiv;
610  HWREG(I2S_BASE + I2S_O_BCLKDIV) = (bclkDiv == 1024 ? 0 : bclkDiv);
611 
612  // Configure the WCLK format and disable CCLK, WCLK and BCLK
613  HWREG(I2S_BASE + I2S_O_CLKCTL) = (dualPhase ? (1 << I2S_CLKCTL_WCLKPHASE_S) : (0 << I2S_CLKCTL_WCLKPHASE_S));
614  }
615 }
616 
617 //*****************************************************************************
618 //
629 //
630 //*****************************************************************************
632 {
633  // Enable CCLK, WCLK and BCLK
634  HWREG(I2S_BASE + I2S_O_CLKCTL) |= I2S_CLKCTL_MEN | I2S_CLKCTL_WBEN;
635 }
636 
637 //*****************************************************************************
638 //
645 //
646 //*****************************************************************************
648 {
649  // Disable CCLK, WCLK and BCLK
650  HWREG(I2S_BASE + I2S_O_CLKCTL) &= ~(I2S_CLKCTL_MEN | I2S_CLKCTL_WBEN);
651 }
652 
653 //****************************************************************************
654 //
671 //
672 //****************************************************************************
673 __STATIC_INLINE void I2SSetInPointer(uint32_t base, uint32_t nextPointer)
674 {
675  // Check the arguments
676  ASSERT(I2SBaseValid(base));
677 
678  HWREG(I2S_BASE + I2S_O_INPTRNXT) = nextPointer;
679 }
680 
681 //****************************************************************************
682 //
699 //
700 //****************************************************************************
701 __STATIC_INLINE void I2SSetOutPointer(uint32_t base, uint32_t nextPointer)
702 {
703  // Check the arguments
704  ASSERT(I2SBaseValid(base));
705 
706  HWREG(I2S_BASE + I2S_O_OUTPTRNXT) = nextPointer;
707 }
708 
709 //****************************************************************************
710 //
716 //
717 //****************************************************************************
718 __STATIC_INLINE uint32_t I2SGetInPointerNext(uint32_t base)
719 {
720  // Check the arguments
721  ASSERT(I2SBaseValid(base));
722 
723  return (HWREG(I2S_BASE + I2S_O_INPTRNXT));
724 }
725 
726 //****************************************************************************
727 //
733 //
734 //****************************************************************************
735 __STATIC_INLINE uint32_t I2SGetOutPointerNext(uint32_t base)
736 {
737  // Check the arguments
738  ASSERT(I2SBaseValid(base));
739 
740  return (HWREG(I2S_BASE + I2S_O_OUTPTRNXT));
741 }
742 
743 //****************************************************************************
744 //
750 //
751 //****************************************************************************
752 __STATIC_INLINE uint32_t I2SGetInPointer(uint32_t base)
753 {
754  // Check the arguments
755  ASSERT(I2SBaseValid(base));
756 
757  return (HWREG(I2S_BASE + I2S_O_INPTR));
758 }
759 
760 //****************************************************************************
761 //
767 //
768 //****************************************************************************
769 __STATIC_INLINE uint32_t I2SGetOutPointer(uint32_t base)
770 {
771  // Check the arguments
772  ASSERT(I2SBaseValid(base));
773 
774  return (HWREG(I2S_BASE + I2S_O_OUTPTR));
775 }
776 
777 //*****************************************************************************
778 //
787 //
788 //*****************************************************************************
789 __STATIC_INLINE void I2SConfigureInSampleStampTrigger(uint32_t base, uint16_t trigValue)
790 {
791  // Check the arguments
792  ASSERT(I2SBaseValid(base));
793 
794  // Setup the sample stamp trigger for input streams
795  HWREGH(I2S_BASE + I2S_O_STMPINTRIG) = trigValue;
796 }
797 
798 //*****************************************************************************
799 //
808 //
809 //*****************************************************************************
810 __STATIC_INLINE void I2SConfigureOutSampleStampTrigger(uint32_t base, uint16_t trigValue)
811 {
812  // Check the arguments
813  ASSERT(I2SBaseValid(base));
814 
815  // Setup the sample stamp trigger for output streams
816  HWREGH(I2S_BASE + I2S_O_STMPOUTTRIG) = trigValue;
817 }
818 
819 //*****************************************************************************
820 //
831 //
832 //*****************************************************************************
833 __STATIC_INLINE void I2SConfigureWclkCounterPeriod(uint32_t base, uint16_t period)
834 {
835  // Check the arguments
836  ASSERT(I2SBaseValid(base));
837 
838  // Configure the WCLK counter period
839  HWREGH(I2S_BASE + I2S_O_STMPWPER) = period;
840 }
841 
842 //*****************************************************************************
843 //
850 //
851 //*****************************************************************************
852 __STATIC_INLINE void I2SConfigureWclkCounter(uint32_t base, int16_t value)
853 {
854  uint16_t minusValue;
855 
856  // Check the arguments
857  ASSERT(I2SBaseValid(base));
858 
859  if (value >= 0)
860  {
861  HWREGH(I2S_BASE + I2S_O_STMPWADD) = value;
862  }
863  else
864  {
865  minusValue = (uint16_t)(-value);
866  HWREGH(I2S_BASE + I2S_O_STMPWADD) = HWREGH(I2S_BASE + I2S_O_STMPWPER) - minusValue;
867  }
868 }
869 
870 //*****************************************************************************
871 //
877 //
878 //*****************************************************************************
880 {
881  // Check the arguments
882  ASSERT(I2SBaseValid(base));
883 
884  HWREGH(I2S_BASE + I2S_O_STMPWSET) = 0;
885 }
886 
887 //*****************************************************************************
888 //
889 // Mark the end of the C bindings section for C++ compilers.
890 //
891 //*****************************************************************************
892 #ifdef __cplusplus
893 }
894 #endif
895 //****************************************************************************
896 //
900 //
901 //****************************************************************************
902 
903 #endif // __I2S_H__
__STATIC_INLINE void I2SStart(uint32_t base, uint16_t dmaLength)
Starts the I2S.
Definition: i2s.h:374
__STATIC_INLINE void I2SConfigureOutSampleStampTrigger(uint32_t base, uint16_t trigValue)
Configure the output sample stamp trigger.
Definition: i2s.h:810
__STATIC_INLINE void I2SConfigureWclkCounter(uint32_t base, int16_t value)
Confiugre the WCLK counter value.
Definition: i2s.h:852
__STATIC_INLINE void I2SConfigureClocks(uint32_t base, bool isController, bool invertWclk, bool dualPhase, uint32_t cclkDiv, uint32_t wclkDiv, uint32_t bclkDiv)
Configure the I2S clocks (CCLK, WCLK and BCLK).
Definition: i2s.h:574
__STATIC_INLINE void I2SEnableControllerClocks(uint32_t base)
Enable the I2S controller clocks (CCLK, WCLK and BCLK).
Definition: i2s.h:631
__STATIC_INLINE void I2SResetWclkCounter(uint32_t base)
Reset the WCLK count.
Definition: i2s.h:879
__STATIC_INLINE void I2SConfigureWclkCounterPeriod(uint32_t base, uint16_t period)
Configure the WCLK counter period.
Definition: i2s.h:833
uint32_t I2SGetSampleStamp(uint32_t base, uint32_t channel)
Get the current value of a sample stamp counter.
Definition: i2s.c:43
__STATIC_INLINE void I2SSetInPointer(uint32_t base, uint32_t nextPointer)
Set the next input buffer pointer.
Definition: i2s.h:673
__STATIC_INLINE void I2SConfigureFrame(uint32_t base, uint8_t sd0Usage, uint8_t sd0Channels, uint8_t sd1Usage, uint8_t sd1Channels)
Setup the two interfaces SD0 and SD1 (also called AD0 and AD1).
Definition: i2s.h:510
__STATIC_INLINE void I2SDisableControllerClocks(uint32_t base)
Disable the I2S controller clocks (CCLK, WCLK and BCLK).
Definition: i2s.h:647
__STATIC_INLINE void I2SDisableInt(uint32_t base, uint32_t intFlags)
Disables individual I2S interrupt sources.
Definition: i2s.h:208
__STATIC_INLINE void I2SSetOutPointer(uint32_t base, uint32_t nextPointer)
Set the next output buffer pointer.
Definition: i2s.h:701
__STATIC_INLINE void I2SEnableInt(uint32_t base, uint32_t intFlags)
Enables individual I2S interrupt sources.
Definition: i2s.h:176
__STATIC_INLINE uint32_t I2SGetInPointerNext(uint32_t base)
Get value of the next input pointer.
Definition: i2s.h:718
__STATIC_INLINE uint32_t I2SGetOutPointerNext(uint32_t base)
Get value of the next output pointer.
Definition: i2s.h:735
__STATIC_INLINE uint32_t I2SGetOutPointer(uint32_t base)
Get value of the current output pointer.
Definition: i2s.h:769
__STATIC_INLINE void I2SDisableSampleStamp(uint32_t base)
Disable the Sample Stamp generator.
Definition: i2s.h:331
#define ASSERT(expr)
Definition: debug.h:71
__STATIC_INLINE uint32_t I2SGetInPointer(uint32_t base)
Get value of the current input pointer.
Definition: i2s.h:752
__STATIC_INLINE void I2SStop(uint32_t base)
Stops the I2S module for operation.
Definition: i2s.h:408
__STATIC_INLINE uint32_t I2SIntStatus(uint32_t base, bool masked)
Gets the current interrupt status.
Definition: i2s.h:240
__STATIC_INLINE void I2SConfigureFormat(uint32_t base, uint8_t dataDelay, uint32_t memoryLength, uint32_t samplingEdge, bool dualPhase, uint8_t bitsPerSample)
Configure the serial format of the I2S module.
Definition: i2s.h:452
__STATIC_INLINE void I2SConfigureInSampleStampTrigger(uint32_t base, uint16_t trigValue)
Configure the input sample stamp trigger.
Definition: i2s.h:789
#define __STATIC_INLINE
Definition: cmsis_gcc.h:47
__STATIC_INLINE void I2SEnableSampleStamp(uint32_t base)
Enable the Sample Stamp generator.
Definition: i2s.h:310
__STATIC_INLINE void I2SClearInt(uint32_t base, uint32_t intFlags)
Clears I2S interrupt sources.
Definition: i2s.h:283