Hardware Timers on Third Generation Devices

Is there any ability to use the hardware timers on third generation devices without going to monolithic firmware? Without these the ability to leverage the M4 in the NRF52840 for real-time DSP is greatly impaired.

1 Like

@dzimmanck, currently there is not. Furthermore, there is only one potential unused hardware timer available. As for “real -time DSP”, given the SoftDevice and Particle stacks running on FreeRTOS, I’m not sure how “real-time” you’ll be able to get on the nRF52840.

Interesting. I had a go at it anyways, as I appear to have access to nrf_drv_timer.h from the app level and was able to compile code which uses one of the hardware timers, but after re-flashing the device it can no longer connect with the particle cloud. I am wondering if I over-wrote a timer which was being used for a critical function in deviceOS.

Any idea which timer isn;t used?

@dzimmanck, I’ll inquire.

I got 10 red blinks after the SOS message, which I guess means I introduced an assertion error.

Here is my code. Attempting to run on an Argon. Basically a high performance blinky program.

#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_drv_timer.h"
#include "app_error.h"

const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(0);

int led1 = D7;

void on_receive(const char *event, const char *data) {

 * @brief Handler for timer events.
void timer_event_handler(nrf_timer_event_t event_type, void* p_context)
    static bool led_is_on = false;
    switch (event_type)
                digitalWrite(led1, LOW);
                led_is_on = false;
                digitalWrite(led1, HIGH);
                led_is_on = true;

            //Do nothing.

void setup() {
    // open the serial port at 9600 bps:
    // subscribe to the power meter data
    Mesh.subscribe("meter-0", on_receive);
    pinMode(led1, OUTPUT);
    uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;
    // Calculate the number of time ticks to program the timer
    time_ticks = nrf_drv_timer_ms_to_ticks(&SIMPLE_TIMER, time_ms);
    // configure the timer
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&SIMPLE_TIMER, &timer_cfg, timer_event_handler);


void loop() {

I was not able to recover my device even after manually re-flashing it over USB. This code appears to kill an Argon.

1 Like

@dzimmanck, ouch! Testing might require a monolithic build. Does the device enter DFU mode?

I am able to get it in DFU mode and the CLI reports successful reflash, but still same error on bootup. I am wondering if I somehow damaged the flasher or the bootloader by changing a timer config setting. I sent a support request to Particle.

I shared the code above. Anyone have another Argon they want to sacrifice to see if the kill code is repeatable? I only had the one.


I think it was the bootloader that I damaged. I was able to recover the device if I first reflash the bootloader:

particle flash --usb “argon-bootloader@1.1.1-rc.1.bin” --force

Very interesting.


@peekay123, you ever able to acquire any more insight to this? My main objective is to build a VERY low-cost power meter, but in order to do proper power calculations, I need to do some operations on multiple ADC channels synchronously in “real-time” (~10kHz). The ARM M4 is plenty powerful to do this, but maybe deviceOS on third gen devices just makes this an ill suited platform architecturally.

@dzimmanck, not sure mesh devices are the right platform given the DeviceOS overhead. I believe most if not all DMA channels are used up. The Photon makes a better platform for what you want and @rickkas7 has a good example of multi-ADC sampling.