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

BLE stack priority options that preserve data read on GPIO pin

I understand that the BLE-stack takes the highest processing priority on the nRF52 (nRF52840 in my case).  So data read on one of the GPIO pins of the nRF52 may be "lost" if the BLE-stack directs away/overrides the running data-read program loop.  I have a data-read loop that needs to be uninterrupted for at least 2ms (milli-seconds) to generate a value which will be sent over the BLE-stack.  The data on the GPIO comes only once in every few seconds.

1. Is there a way to make the data-read process "atomic", as in the AVRs, where an outside event CAN'T  influence it for a given period of time (i.e. 2 ms)?

2. Or is there a way to "store" the read vale until the BLE-stack handes back the processing priority to my data-read process and I can send that data via BLE? 

3. Or, if I set the nRF52 in "central' mode" instead of 'client", would I be able to control when the BLE-stack would run?  Instead of it responding to an outside request at any given time, thus breaking away from my data-read subroutine and potentially compromising the data. 

Note:  the BLE's only task in my code is to send that one data that is being read on the GPIO pin.

  • Hi,

    Can you elaborate on what you want to do (how the data is transmitted, requierments etc) as that determines which way to handle this.

    1. Is there a way to make the data-read process "atomic", as in the AVRs, where an outside event CAN'T  influence it for a given period of time (i.e. 2 ms)?

    The SoftDevice has the multiprotocol timeslot API which can be used for this purpose if the nRF initiates the process (can control when it happens). Then, the application requests a timeslot from the SoftDevice, and when granted, you will know that there cannot be any SoftDevice interrupts for the duration of the timeslot.

    2. Or is there a way to "store" the read vale until the BLE-stack handes back the processing priority to my data-read process and I can send that data via BLE? 

    Unless the data is something simple that you can do with PPI (like incrementing a counter, or starting a timer to measure the duration of a pulse or similar), then typically no. Though if the operation would be a single read or write operation using something like TWI or SPI, then it might work with DMA.

    3. Or, if I set the nRF52 in "central' mode" instead of 'client", would I be able to control when the BLE-stack would run?  Instead of it responding to an outside request at any given time, thus breaking away from my data-read subroutine and potentially compromising the data. 

    That does not have much effect in this case. The point is that you (probably) need to schedule the operation so that your time critical task happens in a period where there is no SoftDevice activity, and those mechanisms are independent of the SoftDevice role. However, you would want to have a bit slack in the connection parameters if using e.g. the timeslot API, so that the SoftDevice can easily schedule in your timeslots.

  • Thank you for the very fast response.

    The details of the working code are in this link below. I believe that it's entirely worked by the GPIOTE-PPI-CAPTURE without any main processor interaction. 

    It's basically a one-shot pulse with a period of 100-1600 us  /micro-secs/  (period: the length between peaks or rising edge)   Once the pulse is "read" by the program it gets sent via BLE, preferably within 500 ms (milli seconds).  After that, the entire process goes into standby and waits for the next single-shot pulse which could come in 1 second or several minutes. 

    So the only time-block that is critical is the reading of the incoming pulse on the single GPIO, which should never be more then 2 ms (mili-seconds) period (length). That is the only time that the process cannot be interrupted as to capture the pulse correctly. 

    devzone.nordicsemi.com/.../nrf52-pulse-duration-counter---going-from-1-micro-second-resolution-to-nano-seconds

    EDIT: reading more about the  "Concurrent Multiprotocol Timeslot API”, this link seems to be relevant:

    https://devzone.nordicsemi.com/nordic/short-range-guides/b/software-development-kit/posts/setting-up-the-timeslot-api

    Question 1:   wondering if  the"Concurrent Multiprotocol Timeslot API” is strictly a nRF SDK solution, or can be implemented in Arduino?  What about python?  I am mostly limited in my programming skills in Arduino.

    Question 2:   if I make use of the Timeslot API in device 1, does that disconnect an existing BLE connection between device 1 and device 2 while I am using the Timeslot?   If yes, and as a result the BLE is lost temporarily (and the device 2 is not programmed to auto-reconnect),  would I be able to ensure a quick resumption of data over BLE to device 2 by setting device 1 to  "central"?

  • Hi,

    fe7565 said:

    It's basically a one-shot pulse with a period of 100-1600 us  /micro-secs/  (period: the length between peaks or rising edge)   Once the pulse is "read" by the program it gets sent via BLE, preferably within 500 ms (milli seconds).  After that, the entire process goes into standby and waits for the next single-shot pulse which could come in 1 second or several minutes. 

    So the only time-block that is critical is the reading of the incoming pulse on the single GPIO, which should never be more then 2 ms (mili-seconds) period (length). That is the only time that the process cannot be interrupted as to capture the pulse correctly. 

    If the only thing you need to do in a timely manner is to capture and measure a length of this pulse, and this pulse comes quite rarely (between one second and several minutes between each time), then this is trivial as it can be handled by combining GPIOTE and TIMER with PPI, as you write. That would be handled entirely in HW, and the only thing you need to do in SW is to configure sometime before the pulse starts, and read the result sometime after it has ended. This should not conflict with the SoftDevice in any way, so you should not need to use timeslots.

    fe7565 said:
    Question 1:   wondering if  the"Concurrent Multiprotocol Timeslot API” is strictly a nRF SDK solution, or can be implemented in Arduino?  What about python?  I am mostly limited in my programming skills in Arduino.

    I do not know how this would be done with Arduino, but if the SoftDevice is used, then the timeslot API should be available.

    fe7565 said:
    Question 2:   if I make use of the Timeslot API in device 1, does that disconnect an existing BLE connection between device 1 and device 2 while I am using the Timeslot?

    No. Using the timeslot API is the SoftDevice will schedule a timeslot in between BLE events. So any connections will stay alive. But this also means that the SoftDevice needs to decide when this happens. If this is triggered by an external event that you cannot control (making it asynchronous), then that approach will not work.

    So to recap, if all you need to do is to measure the duration of a pulse that can happen at any time, but with a long time between each pulse, then this can be done with GPIOTE, Timer and PPI and will work without any problem together with the SoftDevice. No need to use the SoftDevice timeslot API in this case.

  • Thank you very much for your assistance. You gave my answer.

Related