3030// #include "memcpy_interleave.h"
3131#include < arm_math.h>
3232
33+ #if defined(__IMXRT1062__)
34+ #include " utility/imxrt_hw.h"
35+ #endif
3336
3437// Here's the function to change the sample rate of the system (via changing the clocking of the I2S bus)
3538// https://forum.pjrc.com/threads/38753-Discussion-about-a-simple-way-to-change-the-sample-rate?p=121365&viewfull=1#post121365
3639float setI2SFreq (const float freq_Hz) {
40+ #if defined(KINETISK)
3741 int freq = (int )freq_Hz;
3842 typedef struct {
3943 uint8_t mult;
@@ -71,6 +75,7 @@ float setI2SFreq(const float freq_Hz) {
7175 }
7276 }
7377 return 0 .0f ;
78+ #endif
7479}
7580
7681static inline int32_t f32_to_i32 (float32_t f) {
@@ -103,10 +108,9 @@ void AudioOutputI2S_F32::begin(void)
103108
104109 // TODO: should we set & clear the I2S_TCSR_SR bit here?
105110 config_i2s ();
106-
107- CORE_PIN22_CONFIG = PORT_PCR_MUX (6 ); // pin 22, PTC1, I2S0_TXD0
108111
109112#if defined(KINETISK)
113+ CORE_PIN22_CONFIG = PORT_PCR_MUX (6 ); // pin 22, PTC1, I2S0_TXD0
110114 dma.TCD ->SADDR = i2s_tx_buffer;
111115 dma.TCD ->SOFF = 4 ;
112116 dma.TCD ->ATTR = DMA_TCD_ATTR_SSIZE (2 ) | DMA_TCD_ATTR_DSIZE (2 );
@@ -121,13 +125,32 @@ void AudioOutputI2S_F32::begin(void)
121125 // dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; //original
122126 dma.TCD ->BITER_ELINKNO = I2S_BUFFER_TO_USE_BYTES / 4 ;
123127 dma.TCD ->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
124- #endif
125128 dma.triggerAtHardwareEvent (DMAMUX_SOURCE_I2S0_TX);
126- update_responsibility = update_setup ();
127129 dma.enable ();
128130
129131 I2S0_TCSR = I2S_TCSR_SR;
130132 I2S0_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE;
133+
134+ #elif defined(__IMXRT1062__)
135+ CORE_PIN7_CONFIG = 3 ; // 1:TX_DATA0
136+ dma.TCD ->SADDR = i2s_tx_buffer;
137+ dma.TCD ->SOFF = 2 ;
138+ dma.TCD ->ATTR = DMA_TCD_ATTR_SSIZE (1 ) | DMA_TCD_ATTR_DSIZE (1 );
139+ dma.TCD ->NBYTES_MLNO = 2 ;
140+ dma.TCD ->SLAST = -sizeof (i2s_tx_buffer);
141+ dma.TCD ->DOFF = 0 ;
142+ dma.TCD ->CITER_ELINKNO = sizeof (i2s_tx_buffer) / 2 ;
143+ dma.TCD ->DLASTSGA = 0 ;
144+ dma.TCD ->BITER_ELINKNO = sizeof (i2s_tx_buffer) / 2 ;
145+ dma.TCD ->DADDR = (void *)((uint32_t )&I2S1_TDR0 + 2 );
146+ dma.TCD ->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
147+ dma.triggerAtHardwareEvent (DMAMUX_SOURCE_SAI1_TX);
148+ dma.enable ();
149+
150+ I2S1_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE;
151+ I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE;
152+ #endif
153+ update_responsibility = update_setup ();
131154 dma.attachInterrupt (isr);
132155
133156 // change the I2S frequencies to make the requested sample rate
@@ -141,7 +164,7 @@ void AudioOutputI2S_F32::begin(void)
141164
142165void AudioOutputI2S_F32::isr (void )
143166{
144- #if defined(KINETISK)
167+ #if defined(KINETISK) || defined(__IMXRT1062__)
145168 int32_t *dest;
146169 audio_block_f32_t *blockL, *blockR;
147170 uint32_t saddr, offsetL, offsetR;
@@ -359,7 +382,7 @@ void AudioOutputI2S_F32::update(void)
359382 }
360383}
361384
362-
385+ # if defined(KINETISK) || defined(KINETISL)
363386// MCLK needs to be 48e6 / 1088 * 256 = 11.29411765 MHz -> 44.117647 kHz sample rate
364387//
365388#if F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000
@@ -407,8 +430,11 @@ void AudioOutputI2S_F32::update(void)
407430 #endif
408431#endif
409432
433+ #endif
434+
410435void AudioOutputI2S_F32::config_i2s (void )
411436{
437+ #if defined(KINETISK) || defined(KINETISL)
412438 SIM_SCGC6 |= SIM_SCGC6_I2S;
413439 SIM_SCGC7 |= SIM_SCGC7_DMA;
414440 SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
@@ -446,6 +472,66 @@ void AudioOutputI2S_F32::config_i2s(void)
446472 CORE_PIN23_CONFIG = PORT_PCR_MUX (6 ); // pin 23, PTC2, I2S0_TX_FS (LRCLK)
447473 CORE_PIN9_CONFIG = PORT_PCR_MUX (6 ); // pin 9, PTC3, I2S0_TX_BCLK
448474 CORE_PIN11_CONFIG = PORT_PCR_MUX (6 ); // pin 11, PTC6, I2S0_MCLK
475+
476+ #elif defined(__IMXRT1062__)
477+
478+ CCM_CCGR5 |= CCM_CCGR5_SAI1 (CCM_CCGR_ON);
479+
480+ // if either transmitter or receiver is enabled, do nothing
481+ if (I2S1_TCSR & I2S_TCSR_TE) return ;
482+ if (I2S1_RCSR & I2S_RCSR_RE) return ;
483+ // PLL:
484+ int fs = AUDIO_SAMPLE_RATE_EXACT;
485+ // PLL between 27*24 = 648MHz und 54*24=1296MHz
486+ int n1 = 4 ; // SAI prescaler 4 => (n1*n2) = multiple of 4
487+ int n2 = 1 + (24000000 * 27 ) / (fs * 256 * n1);
488+
489+ double C = ((double )fs * 256 * n1 * n2) / 24000000 ;
490+ int c0 = C;
491+ int c2 = 10000 ;
492+ int c1 = C * c2 - (c0 * c2);
493+ set_audioClock (c0, c1, c2);
494+
495+ // clear SAI1_CLK register locations
496+ CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK))
497+ | CCM_CSCMR1_SAI1_CLK_SEL (2 ); // &0x03 // (0,1,2): PLL3PFD0, PLL5, PLL4
498+ CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
499+ | CCM_CS1CDR_SAI1_CLK_PRED (n1-1 ) // &0x07
500+ | CCM_CS1CDR_SAI1_CLK_PODF (n2-1 ); // &0x3f
501+
502+ // Select MCLK
503+ IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1
504+ & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK))
505+ | (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL (0 ));
506+
507+ CORE_PIN23_CONFIG = 3 ; // 1:MCLK
508+ CORE_PIN21_CONFIG = 3 ; // 1:RX_BCLK
509+ CORE_PIN20_CONFIG = 3 ; // 1:RX_SYNC
510+
511+ int rsync = 0 ;
512+ int tsync = 1 ;
513+
514+ I2S1_TMR = 0 ;
515+ // I2S1_TCSR = (1<<25); //Reset
516+ I2S1_TCR1 = I2S_TCR1_RFW (1 );
517+ I2S1_TCR2 = I2S_TCR2_SYNC (tsync) | I2S_TCR2_BCP // sync=0; tx is async;
518+ | (I2S_TCR2_BCD | I2S_TCR2_DIV ((1 )) | I2S_TCR2_MSEL (1 ));
519+ I2S1_TCR3 = I2S_TCR3_TCE;
520+ I2S1_TCR4 = I2S_TCR4_FRSZ ((2 -1 )) | I2S_TCR4_SYWD ((32 -1 )) | I2S_TCR4_MF
521+ | I2S_TCR4_FSD | I2S_TCR4_FSE | I2S_TCR4_FSP;
522+ I2S1_TCR5 = I2S_TCR5_WNW ((32 -1 )) | I2S_TCR5_W0W ((32 -1 )) | I2S_TCR5_FBT ((32 -1 ));
523+
524+ I2S1_RMR = 0 ;
525+ // I2S1_RCSR = (1<<25); //Reset
526+ I2S1_RCR1 = I2S_RCR1_RFW (1 );
527+ I2S1_RCR2 = I2S_RCR2_SYNC (rsync) | I2S_RCR2_BCP // sync=0; rx is async;
528+ | (I2S_RCR2_BCD | I2S_RCR2_DIV ((1 )) | I2S_RCR2_MSEL (1 ));
529+ I2S1_RCR3 = I2S_RCR3_RCE;
530+ I2S1_RCR4 = I2S_RCR4_FRSZ ((2 -1 )) | I2S_RCR4_SYWD ((32 -1 )) | I2S_RCR4_MF
531+ | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
532+ I2S1_RCR5 = I2S_RCR5_WNW ((32 -1 )) | I2S_RCR5_W0W ((32 -1 )) | I2S_RCR5_FBT ((32 -1 ));
533+
534+ #endif
449535}
450536
451537
0 commit comments