Zephyr SPIM does not receive any data from MISO pin

 Hello,

 I'm trying to move from nRF5 SDK with nRF52840 to NCS with nRF5340 and experiencing a lot of problems replacing the nrf driver functions with nrfx.

 Thanks to the other precedents in the devzone, I implemented all the functions except the SPIM Rx.

 The problem is that I see the SPI slave (nRF52840-DK and I checked it works well with another nRF52840-DK) toggles the MISO pin, but the SPI master (nRF5340) cannot read the input.

 Following is the code how I configured the SPIM.

 

nrfx_spim_t spim_adc = NRFX_SPIM_INSTANCE(2);
#define spim_adc_m_length  240
static uint8_t spim_adc_rx_buf[spim_adc_m_length+1];
nrfx_spim_xfer_desc_t spim_adc_desc = NRFX_SPIM_XFER_RX(spim_adc_rx_buf, spim_adc_m_length);
static volatile bool spim_adc_xfer_done;

(...)

void gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	nrfx_err_t err_code = nrfx_spim_xfer(&spim_adc, &spim_adc_desc, 0);
}

void gpiote_init(void)
{
	nrfx_err_t err_code;
	
    err_code = nrfx_gpiote_init(6);

	nrfx_gpiote_in_config_t gpiote_cfg = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);

	err_code = nrfx_gpiote_in_init(pin_spim_fpga_ind, &gpiote_cfg, gpiote_handler);
	if (NRFX_SUCCESS != err_code)
	{
		printk("Init error\n");
	}
	nrfx_gpiote_in_event_enable(pin_spim_fpga_ind, true);
}

(...)

void spim_adc_event_handler(nrfx_spim_evt_t const *p_event, void *p_context)
{
	if (p_event->type == NRFX_SPIM_EVENT_DONE)
	{
		spim_adc_xfer_done = true;
	}
}

void spi_init(void)
{
	nrfx_spim_config_t spim_adc_config = NRFX_SPIM_DEFAULT_CONFIG(pin_spim_adc_CLK, pin_spim_adc_MOSI, pin_spim_adc_MISO, pin_spim_adc_CS);
	spim_adc_config.frequency = NRF_SPIM_FREQ_8M;
	spim_adc_config.mode = NRF_SPIM_MODE_3;
	// nrfx_spim_init(&spim_adc, &spim_adc_config, spim_adc_event_handler, NULL);
	if (NRFX_SUCCESS != nrfx_spim_init(&spim_adc, &spim_adc_config, spim_adc_event_handler, NULL))
	{
		printk("Init error\n");
	}
	IRQ_DIRECT_CONNECT(SPIM2_SPIS2_TWIM2_TWIS2_UARTE2_IRQn, 2, nrfx_spim_2_irq_handler, 0);
	irq_enable(SPIM2_SPIS2_TWIM2_TWIS2_UARTE2_IRQn);
}

(...)

void main(void)
{
	// Set CPU clock to 64 MHz
	HFCLKCTL_R &= ~(0x01);

	// Init
	ble_init();
	nus_init();
	gpio_pin_init();
	spi_init();
	gpiote_init();

	// Load configuration
	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}

	// Start BLE advertising
	advertising_init();
	
	// Enable cache and hit/miss tracking
    while((NVMC_READY_R&0x1) == 0);
    NVMC_ICACHECNF_R = 0x101;

	// Main loop responses to the BLE RX event after the callback
	for(;;)
	{
		if (spim_adc_xfer_done)
		{
			uint16_t length = spim_adc_m_length;
			bt_nus_send(NULL, spim_adc_rx_buf, length);
			spim_adc_xfer_done = false;
		}
	}
}

 As you can see, when the SPI transaction is over, I send the Rx buffer data via Bluetooth. The result is a 240 bytes length array with only zero value.

 Please let me know if I missed something required to enable SPI Rx.

 P.S. The code crashes when I locate the bt_nus_data_send() in the SPIM handler but there was no problem doing so with ble_nus_data_send(). Is this the problem of priority which was managed by SoftDevice before?

Parents Reply Children
  • It is possible that P0.10 is assigned to the Network core for its UART instance

    As you told me, I checked the network core and found the child image 'hci_rpmsg' uses pin P0.10 for the UART instance and zephyr functions.

     As I need to use P0.10, P0.11, and P1.1 for other purposes, I modified the cpu_net overlay file like following

     The overlay file is located in the sdk/zephyr/samples/bluetooth/hci_rpmsg

     However, the SPI data still not coming via P0.10...

  • I also disabled CONFIG_LOG of the network core according to this thread but it still not works

  • The pins are still assigned to the network core domain, even if they are not used by the UART interface. Did you try changing the pin definitions in the file I linked, and/or comment out the calls to soc_secure_gpio_pin_mcu_select()?

  • Did you try changing the pin definitions in the file I linked, and/or comment out the calls to soc_secure_gpio_pin_mcu_select()?

     At first, I thought the file means child image but it was not.

     So, I tried both referencing out and changing the pin assignment

    static void remoteproc_mgr_config(void)
    {
    	/* UARTE */
    	/* Assign specific GPIOs that will be used to get UARTE from
    	 * nRF5340 Network MCU.
    	 */
    	// CPUNET_UARTE_PORT_TRX->PIN_CNF[CPUNET_UARTE_PIN_TX] =
    	// 	GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos;
    	// CPUNET_UARTE_PORT_TRX->PIN_CNF[CPUNET_UARTE_PIN_RX] =
    	// 	GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos;
    	// NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_RTS] =
    	// 	GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos;
    	// NRF_P0->PIN_CNF[CPUNET_UARTE_PIN_CTS] =
    	// 	GPIO_PIN_CNF_MCUSEL_NetworkMCU << GPIO_PIN_CNF_MCUSEL_Pos;
    
    	/* Route Bluetooth Controller Debug Pins */
    	// DEBUG_SETUP();
    
    	/* Retain nRF5340 Network MCU in Secure domain (bus
    	 * accesses by Network MCU will have Secure attribute set).
    	 */
    	NRF_SPU->EXTDOMAIN[0].PERM = 1 << 4;
    }
    #endif /* !CONFIG_TRUSTED_EXECUTION_NONSECURE */

     As the remoteproc_mgr_config() function differs from the thread (there is no soc_secure_gpio_pin_mcu_select() I think), I referenced all the content of that function. But the P0.10 still not working

    /* This should come from DTS, possibly an overlay. */
    #if defined(CONFIG_BOARD_bcc_NRF5340_CPUAPP)
    // #define CPUNET_UARTE_PIN_TX  1
    // #define CPUNET_UARTE_PIN_RX  0
    // #define CPUNET_UARTE_PORT_TRX NRF_P1
    // #define CPUNET_UARTE_PIN_RTS 11
    // #define CPUNET_UARTE_PIN_CTS 10
    
    #define CPUNET_UARTE_PIN_TX  2
    #define CPUNET_UARTE_PIN_RX  3
    #define CPUNET_UARTE_PORT_TRX NRF_P0
    #define CPUNET_UARTE_PIN_RTS 0
    #define CPUNET_UARTE_PIN_CTS 1
    #endif

     Also, assigning other pins did not work. I modified the nrf5340_cpunet_reset.c like upper code.

  • I'm sorry to rush you but is there any additional advice I can try...?

    As I replied, both changing the pin definition and commenting out the calls not worked at all in my case.

Related