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
  • Typically if you are not able to read the pin, it is configured for use/assigned to another peripheral.

     Just as Jorgen said, it seems like the pin P0.10 is assigned as another function. When I change the pin P0.20 as the MISO, for example, the SPI works well.

     Even if I tried to assign P0.10 as GPIO output via nRF GPIO HAL, it does not work...

     What peripheral can take P0.10? The nRF Connect extension of the VS code says that pin is unconnected

  • Hi,

    It is possible that P0.10 is assigned to the Network core for its UART instance, see this thread and this file.

    Best regards,
    Jørgen

  • 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.

Reply Children
Related