Hi,
I'm working on final project wrapup on a device with an nRF5340 using NCS v1.7.1 where the Nordic part is an SPI slave to another processor.
My customer is getting my code running on his board for the first time and he's seeing SPI init errors - I'm checking with him to see if it's occasional or every time. I think I remember getting this error once or twice, but not normally. (the board is custom - but it's the same model board I've been working with so this isn't the first time this code has run on a board like his)
The way this system works, another processor sends us a signal on a GPIO line that tells me to enable the SPI slave peripheral on the Nordic part and get ready to receive SPI comms. I have about 1 millisecond between when the line tells me to enable SPI and when the data starts coming in.
The customer's request was that I completely disable the SPI peripheral between communications to save power as this system is extremely power sensitive.
So, I implemented a GPIO interrupt as follows:
gpio_pin_configure(m_gpio_port_0, SPI_ENABLE_PIN, GPIO_INPUT); gpio_init_callback(&spi_disable_callback, hardware_spi_disable_callback_handler, BIT(SPI_ENABLE_PIN)); gpio_add_callback(m_gpio_port_0, &spi_disable_callback); gpio_pin_interrupt_configure(m_gpio_port_0, SPI_ENABLE_PIN, GPIO_INT_EDGE_RISING);
Then when the GPIO line goes high, it calls spi_disable_callback_handler, which calls a function that sets up the peripheral as follows:
void spi_comms_init(void) { int err; nrf_spis_disable(spi_slave_instance.p_reg); spis_config.orc = 0xFF; // Over-read character. When the master reads more than what we have to send, this is what will be sent err = nrfx_spis_init(&spi_slave_instance, &spis_config, spis_event_handler, NULL); if(err != NRFX_SUCCESS) { printk("SPI Error with init. %d\n", err); } else { //printk("SPIS started.\n"); } spi_comms_send_no_response(); // Start out with a NOIRQ response message ready to go IRQ_DIRECT_CONNECT(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, 0, nrfx_spis_0_irq_handler, 0); irq_enable(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn); nrf_spis_enable(spi_slave_instance.p_reg); timer_start(TIMER_SPI_DISABLE); // Kick the timer that keeps SPI enabled }
So it's not ideal that I'm calling multiple functions and setting up peripherals from an interrupt service handler, but I'm not sure if I have time to set a flag and wait until I get back to the main loop.
Questions:
1) Do you think that configuring the SPI slave peripheral from a GPIO interrupt could be causing a problem?.
2) How much (if any) power am I saving by using nrfx_spis_init and nrfx_spis_uninit to fully enable and disable the peripheral every time vs just setting it up in my init code and using nrf_spis_enable and nrf_spis_disable to turn it on and off? Would this code be more reliable if I just enabled/disabled vs initializing and uninitializing?
Thanks!
Glen