30
30
// #include "memcpy_interleave.h"
31
31
#include < arm_math.h>
32
32
33
+ #if defined(__IMXRT1062__)
34
+ #include " utility/imxrt_hw.h"
35
+ #endif
33
36
34
37
// Here's the function to change the sample rate of the system (via changing the clocking of the I2S bus)
35
38
// https://forum.pjrc.com/threads/38753-Discussion-about-a-simple-way-to-change-the-sample-rate?p=121365&viewfull=1#post121365
36
39
float setI2SFreq (const float freq_Hz) {
40
+ #if defined(KINETISK)
37
41
int freq = (int )freq_Hz;
38
42
typedef struct {
39
43
uint8_t mult;
@@ -71,6 +75,7 @@ float setI2SFreq(const float freq_Hz) {
71
75
}
72
76
}
73
77
return 0 .0f ;
78
+ #endif
74
79
}
75
80
76
81
static inline int32_t f32_to_i32 (float32_t f) {
@@ -103,10 +108,9 @@ void AudioOutputI2S_F32::begin(void)
103
108
104
109
// TODO: should we set & clear the I2S_TCSR_SR bit here?
105
110
config_i2s ();
106
-
107
- CORE_PIN22_CONFIG = PORT_PCR_MUX (6 ); // pin 22, PTC1, I2S0_TXD0
108
111
109
112
#if defined(KINETISK)
113
+ CORE_PIN22_CONFIG = PORT_PCR_MUX (6 ); // pin 22, PTC1, I2S0_TXD0
110
114
dma.TCD ->SADDR = i2s_tx_buffer;
111
115
dma.TCD ->SOFF = 4 ;
112
116
dma.TCD ->ATTR = DMA_TCD_ATTR_SSIZE (2 ) | DMA_TCD_ATTR_DSIZE (2 );
@@ -121,13 +125,32 @@ void AudioOutputI2S_F32::begin(void)
121
125
// dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; //original
122
126
dma.TCD ->BITER_ELINKNO = I2S_BUFFER_TO_USE_BYTES / 4 ;
123
127
dma.TCD ->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
124
- #endif
125
128
dma.triggerAtHardwareEvent (DMAMUX_SOURCE_I2S0_TX);
126
- update_responsibility = update_setup ();
127
129
dma.enable ();
128
130
129
131
I2S0_TCSR = I2S_TCSR_SR;
130
132
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 ();
131
154
dma.attachInterrupt (isr);
132
155
133
156
// change the I2S frequencies to make the requested sample rate
@@ -141,7 +164,7 @@ void AudioOutputI2S_F32::begin(void)
141
164
142
165
void AudioOutputI2S_F32::isr (void )
143
166
{
144
- #if defined(KINETISK)
167
+ #if defined(KINETISK) || defined(__IMXRT1062__)
145
168
int32_t *dest;
146
169
audio_block_f32_t *blockL, *blockR;
147
170
uint32_t saddr, offsetL, offsetR;
@@ -359,7 +382,7 @@ void AudioOutputI2S_F32::update(void)
359
382
}
360
383
}
361
384
362
-
385
+ # if defined(KINETISK) || defined(KINETISL)
363
386
// MCLK needs to be 48e6 / 1088 * 256 = 11.29411765 MHz -> 44.117647 kHz sample rate
364
387
//
365
388
#if F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000
@@ -407,8 +430,11 @@ void AudioOutputI2S_F32::update(void)
407
430
#endif
408
431
#endif
409
432
433
+ #endif
434
+
410
435
void AudioOutputI2S_F32::config_i2s (void )
411
436
{
437
+ #if defined(KINETISK) || defined(KINETISL)
412
438
SIM_SCGC6 |= SIM_SCGC6_I2S;
413
439
SIM_SCGC7 |= SIM_SCGC7_DMA;
414
440
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
@@ -446,6 +472,66 @@ void AudioOutputI2S_F32::config_i2s(void)
446
472
CORE_PIN23_CONFIG = PORT_PCR_MUX (6 ); // pin 23, PTC2, I2S0_TX_FS (LRCLK)
447
473
CORE_PIN9_CONFIG = PORT_PCR_MUX (6 ); // pin 9, PTC3, I2S0_TX_BCLK
448
474
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
449
535
}
450
536
451
537
0 commit comments