This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Can I make one of the nRF5340 pins oscillate at 12.288MHz? (Audio PLL Clock)

I'm trying to avoid buying a 12.288MHz oscillator if I can make one of the pins on the nRF5340 oscillate at that frequency.

It looks like the ACLK is only available to the PDM and I2S peripherals.

Is there a way to make one or both of them use ACLK as its clock source and do a divide-by-1 so that the clock output will be 12.288MHz?

(The PDM or I2S interface doesn't need to "function" as a PDM or I2S peripheral.  It just needs to provide the 12.288MHz clock signal)

Parents Reply Children
  • That worked.

    Here is the code that makes it work:

    #define I2S_MCK_PIN 7 // MCLK pin is P0.07
    
    #define I2S_DATA_BLOCK_WORDS 512 //How many numbers do we want. time reorded = DATA_BLOCK_WORDS / freq
    
    static u32_t m_buffer_rx32u[I2S_DATA_BLOCK_WORDS];
    static nrfx_i2s_buffers_t i2s_initial_buffers;
    
    
    
    // I2S ISR handler
    ISR_DIRECT_DECLARE(i2s_isr_handler)
    {
      nrfx_i2s_irq_handler();
      ISR_DIRECT_PM();  // PM done after servicing interrupt for best latency
      return 1;         // We should check if scheduling decision should be made
    }
    
    // I2S event handler
    static void i2s_data_handler(nrfx_i2s_buffers_t const *p_released, u32_t status)
    {
      if (NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED == status)
      {
        nrfx_i2s_next_buffers_set(&i2s_initial_buffers);
      }
    }
    
    /*****************************************************************************
    * Function: i2s_clk_init
    *
    * Description: provide 12.288MHz reference clock to audio ADC
    *
    * Parameters: none
    *
    * Returns: nothing
    *****************************************************************************/
    static void i2s_clk_init(void)
    {
      // the audio clock defaults to 12.288MHz, so we don't need to adjust it
    
      // configure I2S
      IRQ_DIRECT_CONNECT(I2S0_IRQn, 0, i2s_isr_handler, 0);
      i2s_initial_buffers.p_rx_buffer = m_buffer_rx32u;
    
      nrfx_i2s_config_t i2s_cfg = NRFX_I2S_DEFAULT_CONFIG(NRFX_I2S_PIN_NOT_USED, NRFX_I2S_PIN_NOT_USED, I2S_MCK_PIN, NRFX_I2S_PIN_NOT_USED, NRFX_I2S_PIN_NOT_USED);
      i2s_cfg.clksrc = NRF_I2S_CLKSRC_ACLK; // audio clock
      i2s_cfg.enable_bypass = true;         // bypass division, so we get the raw audio clock
      nrfx_err_t err_code = nrfx_i2s_init(&i2s_cfg, i2s_data_handler);
    
      if(err_code != NRFX_SUCCESS) 
      {
        printf("Error initializing I2S\n");
        return;
      }
    
      // start i2s
      err_code = nrfx_i2s_start(&i2s_initial_buffers, I2S_DATA_BLOCK_WORDS, 0);
      if (err_code != NRFX_SUCCESS)
      {
        printf("I2S start error\n");
      }
    }
    

  • Hi,DBT

    how to adjust audio clock to 16bit 16kHz Left mono?

    thanks

  • I'm not an expert on I2S using nRF5340.  This ticket is about getting the MCLK pin to oscillate.  I wasn't trying to send or receive any I2S data.

    However, at this point I am trying to receive data over I2S, so I'll probably know more within a few weeks.

    Look at section 7.15.3 in the datasheet for the discussion about "mono"

    By "left" do you mean left-aligned or the left channel of audio?  Look at section 7.15.6 in the datasheet.  This same section talks about 16-bit wide data.

    I think for 16kHz sampling you'd want to use PCLK32M rather than ACLK as the clock source.

    You'll probably want to submit a separate ticket in order to get better answers to your specific questions.

Related