Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Teensy 4.0 I2S 96 kHz but no data

  1. #1
    Junior Member
    Join Date
    Feb 2023
    Posts
    6

    Teensy 4.0 I2S 96 kHz but no data

    Hello

    My first post. I am stuck.

    I am using a Teensy 4.0, i have the LRCLK at 96 kHz BCLK at 6.144 mHz and MCLK at 24.576 Mhz.
    The ADC is a WM8782.

    I can use an I2S DAC and get the output from the ADC into the DAC and get sound, but the Teensy doesn't get a signal from the ADC.

    Anyone who can help? as far as i understand the interrupt is tied to BCLK and the Teensy should get the data.

  2. #2
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,243
    Please observe the Forum Rule at the top of the page.

  3. #3
    Junior Member
    Join Date
    Feb 2023
    Posts
    6
    Code:
    void AudioOutputI2S::config_i2s(bool only_bclk)
    {
    	CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON);
    
    	// if either transmitter or receiver is enabled, do nothing
    	if ((I2S1_TCSR & I2S_TCSR_TE) != 0 || (I2S1_RCSR & I2S_RCSR_RE) != 0)
    	{
    	  if (!only_bclk) // if previous transmitter/receiver only activated BCLK, activate the other clock pins now
    	  {
    	    CORE_PIN23_CONFIG = 3;  //1:MCLK
    	    CORE_PIN20_CONFIG = 3;  //1:RX_SYNC (LRCLK)
    	  }
    	  return ;
    	}
    
    	//PLL:
    	int fs = 96000 + 202;
    	int oversampling = 256;
    	int clk = 24000000;
    	// PLL between 27*24 = 648MHz und 54*24=1296MHz
    	int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
    	int n2 = 1 + (clk * 27) / (fs * oversampling * n1);
    
    	double C = ((double)fs * oversampling * n1 * n2) / clk;
    	int c0 = C; //28
    	int c2 = 10000;
    	int c1 = C * c2 - (c0 * c2);
    
    	set_audioClock(c0, c1, c2); //set_audioClock(int nfact, int32_t nmult, uint32_t ndiv, bool force)
    
    	// clear SAI1_CLK register locations
    	CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK))
    		   | CCM_CSCMR1_SAI1_CLK_SEL(2); // &0x03 // (0,1,2): PLL3PFD0, PLL5, PLL4
    	CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
    		   | CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
    		   | CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
    
    	// Select MCLK
    	IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1
    		& ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK))
    		| (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0));
    
    	if (!only_bclk)
    	{
    	  CORE_PIN23_CONFIG = 3;  //1:MCLK
    	  CORE_PIN20_CONFIG = 3;  //1:RX_SYNC  (LRCLK)
    	}
    	CORE_PIN21_CONFIG = 3;  //1:RX_BCLK
    
    	int rsync = 0;
    	int tsync = 1;
    
    	I2S1_TMR = 0;
    	//I2S1_TCSR = (1<<25); //Reset
    	I2S1_TCR1 = I2S_TCR1_RFW(1);
    	I2S1_TCR2 = I2S_TCR2_SYNC(tsync) | I2S_TCR2_BCP // sync=0; tx is async;
    		    | (I2S_TCR2_BCD | I2S_TCR2_DIV((1)) | I2S_TCR2_MSEL(1));
    	I2S1_TCR3 = I2S_TCR3_TCE;
    	I2S1_TCR4 = I2S_TCR4_FRSZ((2-1)) | I2S_TCR4_SYWD((32-1)) | I2S_TCR4_MF
    		    | I2S_TCR4_FSD | I2S_TCR4_FSE | I2S_TCR4_FSP;
    	I2S1_TCR5 = I2S_TCR5_WNW((32-1)) | I2S_TCR5_W0W((32-1)) | I2S_TCR5_FBT((32-1));
    
    	I2S1_RMR = 0;
    	//I2S1_RCSR = (1<<25); //Reset
    	I2S1_RCR1 = I2S_RCR1_RFW(1);
    	I2S1_RCR2 = I2S_RCR2_SYNC(rsync) | I2S_RCR2_BCP  // sync=0; rx is async;
    		    | (I2S_RCR2_BCD | I2S_RCR2_DIV((1)) | I2S_RCR2_MSEL(1));
    	I2S1_RCR3 = I2S_RCR3_RCE;
    	I2S1_RCR4 = I2S_RCR4_FRSZ((2-1)) | I2S_RCR4_SYWD((32-1)) | I2S_RCR4_MF
    		    | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
    	I2S1_RCR5 = I2S_RCR5_WNW((32-1)) | I2S_RCR5_W0W((32-1)) | I2S_RCR5_FBT((32-1));
    }
    this is the code I've changed (i just copied the entire function), I've only changed fs to get the clock frequencies mentioned. the rest of the code is also in "C:\Program Files (x86)\Arduino\hardware\teensy\avr".

  4. #4
    Senior Member
    Join Date
    Jul 2014
    Posts
    3,497
    @Gkatos,
    You still have not provided the code to reproduce the problem.

  5. #5
    Senior Member
    Join Date
    Sep 2021
    Posts
    186
    Quote Originally Posted by Gkatsos View Post
    as far as i understand the interrupt is tied to BCLK
    No, it is tied to the DMA buffer (half-full/full)

    And I'd say yes, it's likely that the code you posted is not the problem.

  6. #6
    Junior Member
    Join Date
    Feb 2023
    Posts
    6
    Here are some of the code examples:

    This will write "Done", if there is a sample
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s;           //xy=619,408
    AudioRecordQueue         queue;         //xy=786,408
    AudioConnection          patchCord1(i2s, 0, queue, 0);
    // GUItool: end automatically generated code
    
    
    
    void setup() 
    { 
      queue.begin();
    }
    
    void loop() 
    {  
      while (queue.available())
      {
        Serial.println("Done");
        queue.clear();
      }
    }
    This writes available packs, for me it writes 0.
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s;           //xy=619,408
    AudioRecordQueue         queue;         //xy=786,408
    AudioConnection          patchCord1(i2s, 0, queue, 0);
    // GUItool: end automatically generated code
    
    
    
    void setup() 
    { 
      queue.begin();
    }
    
    void loop() 
    {  
      Serial.println(queue.available());
    }
    This should just pass the data from ADC to DAC
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s;           //xy=619,408
    AudioOutputI2S           i2s2;           //xy=765,407
    AudioConnection          patchCord1(i2s, 0, i2s2, 0);
    AudioConnection          patchCord2(i2s, 1, i2s2, 1);
    // GUItool: end automatically generated code
    
    
    void setup() 
    { 
      
    }
    
    void loop() 
    {  
    
    }
    For more information on how to use the audio lib: https://www.pjrc.com/teensy/td_libs_Audio.html

  7. #7
    Junior Member
    Join Date
    Feb 2023
    Posts
    6
    I have solved the problem:
    Code:
    void setup() 
    {
      AudioMemory(128); 
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •