nRF5340 I2S is great for ADC clock generation! Assuming this is valid?

So I needed a 2.048Mhz clock for an ADC such that it would sample precisly at the advertised rates but a dedicated xtal was left off the design and nRF5340 timers can only divide down the 16.000Mhz PCLK, leaving me with 2.000Mhz and a "500SPS" on the ADC was really 492 or so.  But then I see the HFCLKAUDIO on the block diagram and tracked where it went.  Highly programmable and accurate and when you configure the I2S MCK correctly out pops a very precise 2.048Mhz!  My question is is this a valid configuration just leaving the MCK running with the TX and RX disabled and the RAM pointers at 0? It is not going to cause an issue at some point down the road? Partly using NRFX and partly registers to avoid the API buffer requirements.  Sadly seems you have to assign sck and lrck for it to work though, even though I do not want them.

static void init_i2s(void)
 {	
	//start the audio clock @ 12.288MHZ FOR USE IN I2S. Set to always run
	NRF_CLOCK->HFCLKAUDIO.FREQUENCY = 39854;
	NRF_CLOCK->HFCLKAUDIOALWAYSRUN = 1;
	NRF_CLOCK->TASKS_HFCLKAUDIOSTART = 1;

 	//configure the I2S just to run the MCK without TX/RX enabled
	nrfx_i2s_config_t config;
 	config.mck_pin = 6;
	config.sck_pin = 37; //mandatory
	config.lrck_pin = 39;  //mandatory
	config.sdin_pin = NRFX_I2S_PIN_NOT_USED;
	config.sdout_pin = NRFX_I2S_PIN_NOT_USED; 
 	config.mck_setup = 660762624;	//per datasheet I2S section this value with a @ 12.288Mhz ACK and 64x multiplier gives 2.048Mhz MCK
	config.mode = NRF_I2S_MODE_MASTER;
	config.format = NRF_I2S_FORMAT_I2S;
	config.ratio = NRF_I2S_RATIO_64X;
	config.clksrc = NRF_I2S_CLKSRC_ACLK;
	config.sample_width = NRF_I2S_SWIDTH_16BIT;
	config.alignment = NRF_I2S_ALIGN_LEFT;
	config.skip_psel_cfg = false;
	config.skip_gpio_cfg = false;
	config.enable_bypass = false;

 	nrfx_i2s_init(&config, NULL);

	//TXEN is on by default, disable
	NRF_I2S0->CONFIG.TXEN = 0;

	//not using the NRFX API for this as it requires buffers be provided, just want the MCK
	NRF_I2S0->ENABLE = 1;
	NRF_I2S0->TASKS_START = 1;
 }

  • Hi,

    I have tried something similar in a nRF52840. I did not see any issues with this approach there, but I cannot make any guarantees that you will not run into issues. 

    If it runs correctly when you try it out, I don't see what issues you could expect later though (apart from needing the I2S peripheral or pins for some other purposes).

    Best regards,
    Jørgen

  • Yeah I could not see any issue either from reading the spec documents but just wondered as it is a non conventional use.  That HFCLKAUDIO is great, so accurate and programable, in the range useful for audio anyway!

    FYI for future readers you can actually claim back the sck and lrck pins.  Even though the NRFX API needs them to init it seems to have no effect after init to just:

    //deconfigure unused pins
    	nrf_gpio_cfg_default(config.sck_pin);
    	nrf_gpio_cfg_default(config.lrck_pin);
    	NRF_I2S0->PSEL.LRCK = NRF_I2S_PIN_NOT_CONNECTED;
    	NRF_I2S0->PSEL.SCK = NRF_I2S_PIN_NOT_CONNECTED;

Related