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

nRF environment coding suggestions

Dear all,

I am facing small problems, which I guess most of you faced at some moment.

I am trying to switch from working with ST microcontrollers to working with nRF52. Both of them are pretty similar, so that's cool. On ST (and not only), I wrote tons of libraries for working with various sensors, actuators, etc. They aren't in any way bound to any HAL. However, most of them have two specific functions: an init() function which is ran in the begining, and a main_loop() function, which should be called on the for(;;) loop. There are also functions that needs to be called by specific interrupts.

Usually my main() function look like this:

bsp_init();
init_1();
init_2();
init_3();
init_4();
for(;;)
{
	bsp_loop();
	loop_1();
	loop_2();
	loop_4();
}

I've tried running some code, and everything looks ok, especially if I don't use the high level drivers you provide (for example, UART, and you'll see later why), and I initialize it by registers. In this code, it did not involve any SoftDevice or radio code.

The reason I want to use your ICs is that on earlier projects, whenever I needed BLE, I used to have the ST micro and a nRF51822 or similar, commmunicating via UART between them, and on the nRF I only had a modified version of the ble_peripheral_app_uart example. Now I want to move everything in the nRF micro, to have both BLE and my application in the same chip, and of course, I have a lot of questions. Here are some of them:

(1) Is there a way to use my libraries as is, meaning that on the main() infinite loop I can call my loops ? If there is, how can I control the power management, the clock, interrupts, etc. ? In the BLE examples you provided, I noticed that on the infinite loop, the sd_app_evt_wait() function is called, and as far as I understood, that handles power, clock, sleep, etc. But in my application, I would like to use, for example, 2 external peripherals:

  • an I2C accelerometer
  • an UART GSM module

In my previous applications, I configure the I2C (I see that you have something equivalent to I2C), then the UART, and afterwards I have a non-blocking loop with various state machines or asynchronous callbacks for them, which all are ran by the main() loop. The interrupts I'm using don't do processing of data or anything that's time consuming, leaving the time consuming stuff for the main() loop (some sort of top-down design).

Now, I have an even more complicated scenario. For the accelerometer, whenever I get 1000 samples, I need to run some spectral functions. Before having 1000 samples, I can run in low power mode, but when I need to compute, I need to speed up the CPU. And I don't have a clue on how to begin understanding this on the nRF micros, while also running the SoftDevice. Can you provide me with some info, or some examples on this ? I mean, not everything I've described above, but at least a starting point with a bit of guidance.

(2) I've read that the SoftDevice restricts access to some of the perihperals (such as clock, etc). I've found in the documentation what the SD restictions are, but it's unclear to me whether I absolutely need to use the nrf_drivers, or I can modify part of them. For example, in the ble_peripheral_app_uart from the example, up to my knowledge and understanding, almost every piece of code there is called by an interrupt, and not by a main loop. When the UART receives bytes, the ISR calls the callback function that is used in main.c, which adds the respective bytes to the BLE stack for sending. I've looked over the ISR function for the UART, and it's way too general for my code, that's why I would like to rewrite it.

(3) Regarding (1) and (2), is there a mechanism to control the clock and sleep while using the SoftDevice ? Or are there any presentations or tutorials that focus strictly on the SoftDevice mechanisms and functions, beside the classic documentation (I've downloaded the latest offline documentation for that) ?

(4) All the above questions were implying using the nRF as a BLE Peripheral, and most of my projects will do that. But I also have questions regarding using the nRF as a multi-link central. As far as I've read, S132 latest version can simultaneously connect to up to 20 peripherals using BLE 4.2. I haven't got the chance to test that, but are you planing on supporting at least 20 also in the S140 BLE 5 ? I would pretty much like to use BLE 5 in order to get a better connection in terms of indoor range (the target is about 20m indoor, which I've understood is feasible), and a lower power consumption.

I think this got pretty bing, and when we'll consume the items here, I'll read more and ask again if I have more questions.

Thank you very much for your support!

Kind regards, Adrian

  • FormerMember
    0 FormerMember

    1) If some processing is continuously being done in the main loop (for(;;) ), it will not be possible to have some power management. If you want some power management (power saving), I would recommend you to run the application "interrupt driven". If you run the application "interrupt driven", the chip does only need to wake up upon events, BLE events, TWI (I2C) events, and UART events, and go back to sleep (system ON) when the processing of those events is finished.

    If you have interrupts that require some processing time (the 1000 samples), you can push processing of those samples to a separate interrupt, running on lower priority than UART/TWI/BLE, so that you don't miss any interrupts when doing the processing, and the chip can go to sleep when the processing has finished.

    The following example shows how to push processing to another interrupt: ble_app_uart_test_throughput_irq.zip (SDK 12.0.0, S132 v.3.0.0) The relevant part is everything related to DATA_SEND_IRQ. The interrupt is borrowed from an unused peripheral.

    2) The purpose of the drivers is to make it easier to use a given peripheral. Whether or not you want to use the drivers is up to you. The ideal thought is that it should not be necessary to modify the drivers, however, if you need/want to modify them, you are free to do so.

    3) When the softdevice is enabled, the LFCLK will run continuously. The softdevice specification explains how the softdevice work. The HFCLK will be controlled by the softdevice, so if your application needs the HFLCK, the sd_clock_hfclk_xxx() API should be used.

    sd_app_wait() puts the chip in system ON.

    4) Related to the questions above, it would not make any difference if the chip is a BLE peripheral, central, or both.

    The two latest versions of S140, S140 v.5.0.0-2.alpha and S140 v. 5.0.0-3-alpha, both support up to 20 concurrent connections.

    A range of 20 m is not so much, and it should normally be quite easy to obtain that.

Related