Two SPIs conflict

Dear all,

I have some problem with SPIs co-work.

I enabled two SPI instances in this project.

  • SPI Instance 1 function(non blocking mode - DMA enabled, 4Mbps):  reading data from SPI sensor while DRDY pin triggered by sensor
  • SPI Instance 2 function(blocking mode - DMA enabled, 8Mbps):  writing collected data to external FLASH sotrage

 Rough frame of my software is:

  1. DRDY signal generated by sensor and trigger gpiote_handler
  2. SPI Instance 1 read and pack data from sensor in gpiote_handler(which might trigger SPI 1 handler several times)
  3. In main while loop, nRF52840 send data pack via ble then write the data pack to FLASH

The problem is, if I enable only SPI instance 1 to collect data and send it through ble, the received data is successive. But when I turn on both SPI instances at the same time, received data seems lost periodically every time I write data into FLASH. Seems like the problem is cuased by SPI conflicts but I highly doubt that since SPI instance 2 was set blocking mode and placed in main loop, which mean it could be interrupt by SPI instance one, right? P.S.: all of the IRQ priorities are default as 6, I tried to turn DRDY IRQ priority to 5 and SPI 1 priority to 4 but still suffered from packet lost. 

Due to large data rate of sensor, DRDY signal comes quite frequently(about 8ms per signal),  the window might not big enough for both getting data and saving data?

Anything wrong with my logic? Can I achieve this with other methods(for example use PPI to connect SPI instance 1 and DRDY pin so that I can spare CPU from getting data?)

Your help is appreciated and please make sure to let me know if any further information is needed?

Thanks,

Ava

  • Hi,

    Conseptually what you write should work. Though I don't quite understand why you want to use blocking mode for SPI instance 2, you can still call it from main() even if you are using non-blocking mode. That should free up time in main handling ble or other events, instead of just waiting for an SPI instance 2 to complete a transfer. So I suggest to look into that for a start.

    In addition I am hoping you can have some GPIO's here that you can use for debugging to try to understand what is actually occuring when data is lost. E.g.

    gpio1 - toggle when entering and exiting gpiote handler
    gpio2 - toggle before and after spi1 transfer
    gpio3 - toggle before and after spi2 transfer
    gpio4 - toggle each time you are writing data to the softdevice

    Best regards,
    Kenneth

  • Hi Kenneth,

    Thanks for your advice.

    If I managed to switch spi 2 to non-blocking mode, I'll stil need a

    while(!spi_xfer_done)
    {
        __WFE();
    }
    after each transfer right? So I thought it might be no difference from blocking mode. Or do we have any method to avoid using while loop in main?

    Anyway I'll work on turning spi 2 to non-blocking mode first.

    Regards,

    Ava

  • Hi,

    You can do something like:

    spi2_handler()
    {
    spi_xfer_done = true;
    }
    
    main()
    {
    ...
    spi_xfer_done = true;
    ...
    while(1)
    {
      if(spi_xfer_done == true)
      {
        // it's possible to execute next spi2 transfer
      }
      // do other stuff
      
      sd_app_evt_wait(); // similar to WFE();
    }
    }
    

    Best regards,
    Kenneth

  • Hi,

    I managed to solve the problem by wirting in only one sector to flash at a time...But might not gonna work if sample rate is doubled.

    Your suggestion is helpful, I'll modify the spi 2 structure for further development.

    Best regards,

    Ava

Related