From bea04bd3485073a45ae6fafdb38a7d04f4219a24 Mon Sep 17 00:00:00 2001
From: jcj83429 <jcj83429@gmail.com>
Date: Wed, 23 Dec 2020 20:16:25 -0800
Subject: [PATCH] try to fix I2s glitching out when setI2SFreq was enabled for
 T4.x

The reference manual suggests that the I2S needs to be disabled and clock-gated when changing the clock params
---
 output_i2s_f32.cpp | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/output_i2s_f32.cpp b/output_i2s_f32.cpp
index 2a55de3..0a9b5c7 100644
--- a/output_i2s_f32.cpp
+++ b/output_i2s_f32.cpp
@@ -93,6 +93,17 @@ float setI2SFreq(const float freq_Hz) {
   Serial.println(C, 4);
   */
 
+  // The CCM_CSCMR1 documentation says that the users of the clock should 
+  // be disabled and the clock gated before changing the clock parameters.
+  
+  // turn off the I2S output first
+  I2S1_RCSR &= ~(I2S_RCSR_RE | I2S_RCSR_BCE);
+  I2S1_TCSR &= ~(I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE);
+  while((I2S1_RCSR & (I2S_RCSR_RE | I2S_RCSR_BCE)) ||
+        (I2S1_TCSR & (I2S_TCSR_TE | I2S_TCSR_BCE)));
+  // gate the SAI1 clock
+  CCM_CCGR5 &= ~CCM_CCGR5_SAI1(3);
+  
   // PLL
   set_audioClock(c0, c1, c2, true);
   // divider after PLL
@@ -100,6 +111,11 @@ float setI2SFreq(const float freq_Hz) {
        | CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
        | CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
 
+  CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON);
+
+  I2S1_RCSR |= (I2S_RCSR_RE | I2S_RCSR_BCE);
+  I2S1_TCSR |= (I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE);
+
   return freq_Hz;
 
 #endif