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

Using 16MHz SPIM on nRF5340-PDK

I have SPIM working at 8MHz on nRF5340-PDK

I want to increase the SPIM speed to 16MHz.

The errata for nRF5340 states "In 128 MHz mode, SPIM max receive frequency is 16 Mbps. In 64 MHz mode, SPIM max receive frequency is 8 Mbps."

So I need to increase the core frequency from 64MHz to 128MHz and increase the SPIM clock frequency from 8MHz to 16MHz.

To change the core frequency to 128MHz do I just manually write HFCLKCTRL sometime during initialization, or is there some kind of zephyr/project setting that controls this?

I tried putting these lines at the beginning of main()

*((volatile uint32_t *)0x50039530ul) = 0xBEEF0044ul;
NRF_CLOCK_S->HFCLKCTRL = CLOCK_HFCLKCTRL_HCLK_Div1 << CLOCK_HFCLKCTRL_HCLK_Pos;

On a secure build, it doesn't seem to cause a problem

On a non-secure build, this causes some kind of repeating reset.  Can you tell me why?

It looks like zephyr/drivers/spi/spi_nrfx_spim.c does not let me set the SPI frequency to 16MHz for the nRF5340.

static inline nrf_spim_frequency_t get_nrf_spim_frequency(u32_t frequency)
{
	/* Get the highest supported frequency not exceeding the requested one.
	 */
	if (frequency < 250000) {
		return NRF_SPIM_FREQ_125K;
	} else if (frequency < 500000) {
		return NRF_SPIM_FREQ_250K;
	} else if (frequency < 1000000) {
		return NRF_SPIM_FREQ_500K;
	} else if (frequency < 2000000) {
		return NRF_SPIM_FREQ_1M;
	} else if (frequency < 4000000) {
		return NRF_SPIM_FREQ_2M;
	} else if (frequency < 8000000) {
		return NRF_SPIM_FREQ_4M;
#if defined(CONFIG_SOC_NRF52833) || defined(CONFIG_SOC_NRF52840)
	} else if (frequency < 16000000) {
		return NRF_SPIM_FREQ_8M;
	} else if (frequency < 32000000) {
		return NRF_SPIM_FREQ_16M;
	} else {
		return NRF_SPIM_FREQ_32M;
#else
	} else {
		return NRF_SPIM_FREQ_8M;
#endif
	}
}

I tried bypassing the "#if defined" part like this

static inline nrf_spim_frequency_t get_nrf_spim_frequency(u32_t frequency)
{
	/* Get the highest supported frequency not exceeding the requested one.
	 */
	if (frequency < 250000) {
		return NRF_SPIM_FREQ_125K;
	} else if (frequency < 500000) {
		return NRF_SPIM_FREQ_250K;
	} else if (frequency < 1000000) {
		return NRF_SPIM_FREQ_500K;
	} else if (frequency < 2000000) {
		return NRF_SPIM_FREQ_1M;
	} else if (frequency < 4000000) {
		return NRF_SPIM_FREQ_2M;
	} else if (frequency < 8000000) {
		return NRF_SPIM_FREQ_4M;
	} else if (frequency < 16000000) {
		return NRF_SPIM_FREQ_8M;
	} else if (frequency < 32000000) {
		return NRF_SPIM_FREQ_16M;
#if defined(CONFIG_SOC_NRF52833) || defined(CONFIG_SOC_NRF52840) || defined(CONFIG_SOC_NRF5340)
	} else {
		return NRF_SPIM_FREQ_32M;
#else
	} else {
		return NRF_SPIM_FREQ_8M;
#endif
	}
}

And in my overlay file I set spi-max-frequency = <16000000>;

But this results in an SPIM clock frequency of 634kHz, for both secure and non-secure builds.

What am I missing?

Related