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

SPIM could not enter spi_xfer_handler function when app timer is used.

Hi,

Good day!

In our application, we are using the SPI protocol to communicate with the LED driver. For a graphic effect like text scroll on the screen, we used nrf_delay_ms() function but this is blocking the CPU time. So we decided to go with the app_timer library to implement this text scroll effect and other graphics. 

Problem:

When this app timer is used to have the delay effect, the nrf_drv_spi_xfer() is not entering into the SPI transfer done handler and the m_xfer_done flag is never updated, therefore its i stuck in this while loop.

while (!spi_xfer_done) {
__WFE();
}

I appreciate any help in this regard.

/**LED SPI transfer function**/
__STATIC_INLINE
void led_spi_transfer(uint8_t led_array[])
{

  if (led_array[0] != 0);
  else if (led_array[0] == 0)
    return;
  //Reset rx buffer and transfer done flag
  memset(m_rx_buf, 0, m_length);
  spi_xfer_done = false;

  APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, led_array, m_length, m_rx_buf, m_length));

  while (!spi_xfer_done) {
    __WFE();
  }
  nrf_delay_us(1);
}

Parents
  • Update: Found a post on Nordic devzone, it says this could happen due to the interrupt nesting, deadlock effect. I was able to solve this by setting SPI task priority in sdk_config.h file to value 3, while an app_timer config priority to value 7. This has solved the issue.

    And we have got few other modules in our application, for example, we use a capacitive touch interface with nrf52832 and it requires an app timer to differentiate between the 3 seconds long touch or 8-second long touch. 

    So, I got a few queries here in regard to the implementation part of different peripheral interfaces. 

    1. Kindly share some resources which could explain interrupt nesting in nrf52832. 

    2. Can I use multiple app_timer instances to deal with the led screen driver which uses SPI and capacitive touch sensor which uses TWI?

    Or Just use one app_timer instance and use multiple counters?

    3. We also have Li-Ion battery SMBus com fon charge controller, Li-Ion voltage and current sense over the SAADC, So please share some insights on how to interface all such modules so that they can work all work in sync.

    Kindly share the related resources.

    Thank you

    Aim High.

Reply
  • Update: Found a post on Nordic devzone, it says this could happen due to the interrupt nesting, deadlock effect. I was able to solve this by setting SPI task priority in sdk_config.h file to value 3, while an app_timer config priority to value 7. This has solved the issue.

    And we have got few other modules in our application, for example, we use a capacitive touch interface with nrf52832 and it requires an app timer to differentiate between the 3 seconds long touch or 8-second long touch. 

    So, I got a few queries here in regard to the implementation part of different peripheral interfaces. 

    1. Kindly share some resources which could explain interrupt nesting in nrf52832. 

    2. Can I use multiple app_timer instances to deal with the led screen driver which uses SPI and capacitive touch sensor which uses TWI?

    Or Just use one app_timer instance and use multiple counters?

    3. We also have Li-Ion battery SMBus com fon charge controller, Li-Ion voltage and current sense over the SAADC, So please share some insights on how to interface all such modules so that they can work all work in sync.

    Kindly share the related resources.

    Thank you

    Aim High.

Children
  • Hi,

    The different modules of the nRF52832 runs on a certain interrupt priority, this priority can be configured in the sdk_config file of the project. The interrupt model is documented here.It's also important to note that each peripheral has assigned an instantiation ID which indicates which resources the peripheral is using. You can't therefore use two peripherals that has the same ID. Using multiple instances of the app timer module is fine. SDK16 has a new improved version of the app timer which can be imported to an older SDK by following the guide here. The first thing that you need to ensure is that you use instances of the peripherals that doesn't use the same resources. Then you could proceed to merge examples from the SDK that use the peripherals that you're going to use. Here is an demo that use the SAADC and UART. Note, the demo is an unsupported project.

    regards

    Jared

Related