This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timers not working when using C++?

So. After countless hours of messing around, reading SDK, examples and stuff I'm begginning to feel kind of frustrated. I want a microsecond timer. For that I tried a number of different approaches: app_timer, timer driver API and accessing the timers directly. So far app_timer seems to be the only one that worked, but it lacks in resolution I need.

Approach 1:

nrf_drv_timer_t timerThing = NRF_DRV_TIMER_INSTANCE(1);

void timerHandler(nrf_timer_events_t event)
{
	if(event == NRF_TIMER_EVENTS_COMPARE0) log("time!\r\n");
}

void main()
{
	log("init\r\n");
	uint32_t ticks, ms = 2000;
	
	nrf_drv_timer_init(&timerThing, NULL, timerHandler);
	ticks = nrf_drv_timer_ms_to_ticks(&timerThing, ms);
	nrf_drv_timer_extended_compare(&timerThing, NRF_TIMER_CC_CHANNEL0, ticks, NRF_TIMER_SHORTS_COMPARE0_CLEAR_MASK, true);
	nrf_drv_timer_enable(&timerThing);
	
	while(1);
	return 0;
}

I looked into 'examples/peripheral/timer', basically copied the code just to get it running. Well.. The handler IS called just fine, the problem however is the fact that it's being called constantly. It doesn't matter what value I set for 'ms' variable. I checked the value returned by ms to ticks conversion function and it appears to be correct.

So I started to look around the devzone and I noticed that people were usually using these timers directly (if what I'm saying makes any sense).

volatile bool foobar = false;

void TIMER1_IRQHandler()
{
    if(NRF_TIMER1->EVENTS_COMPARE[0])
    {
        NRF_TIMER1->EVENTS_COMPARE[0] = 0;
        foobar = true;
    }
}

void uartEventHandler(app_uart_evt_t *event) {}

int main()
{
    uint32_t errorCode;
    
    app_uart_comm_params_t uartParams =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_DISABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud115200 // 57600 // 115200
    };

    APP_UART_FIFO_INIT(&uartParams, 32, 256, uartEventHandler, APP_IRQ_PRIORITY_LOW, errorCode);
    
    debugOut("Hello World!\r\n");
    
    NRF_TIMER1->EVENTS_COMPARE[0] = 0;
    NRF_TIMER1->EVENTS_COMPARE[1] = 0;
    NRF_TIMER1->EVENTS_COMPARE[2] = 0;
    NRF_TIMER1->EVENTS_COMPARE[3] = 0;
    
    NRF_TIMER1->TASKS_STOP  = 1;
    NRF_TIMER1->MODE        = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
    NRF_TIMER1->BITMODE     = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER1->PRESCALER   = 9;
    NRF_TIMER1->TASKS_CLEAR = 1;
    NRF_TIMER1->CC[0] = 31250;
    NRF_TIMER1->INTENSET    = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
    NRF_TIMER1->SHORTS      = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
    NVIC_EnableIRQ(TIMER1_IRQn);
    NRF_TIMER1->TASKS_START = 1;
    
    while(1)
    {
        if(foobar)
        {
            debugOut("foo\r\n");
            foobar = false;
        }
        else debugOut("no\r\n");
    }
    
    return 0;
}

This at first wasn't working. It appeared as if it got stuck inside the interrupt or something. After compiling it with Keil it worked at first but then I did something that made it stop. Now I can't get it to work again:

image description

I'm obviously doing something very wrong, I'm just unable to find out what exactly it is. What am I missing here? Please forgive me if it's something rather silly, I'm still trying to learn the way everything works here.

EDIT:

I found something interesting. This is the code that orginally worked: http://pastebin.com/CGGxRLhs

It's C. After putting in in a .cpp file (compiling as C++) it doesn't work. Putting in in a .c file makes it work just fine...

Related