Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
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

Nrf52 simple Baremetal timer function, CPU reset if interrupt enabled.

Trying to use the basic baremetal mode as my application is very simple and dont want to go through RTOS stuff.

I tried with Timer and RTC, both case if I enable the interrupt then the cpu gets rebooted.
Following is the code, not sure if it is the way I am building the code or some other parameter is messing things up.

This example if basically "..\..\sdk\nRF5_SDK_17.1.0_ddde560\examples\peripheral\timer"
I will try to upload the zip of the full project. Different peripheral works except the Interrupt part.

#include <stdio.h>
#include <nrf.h>

#define PIN_LED1 (17UL) // nrf52-dk
volatile bool bLED1Set= false;
int main(void)
{
// Start LFCLK (32kHz) crystal oscillator. If you don't have crystal on your board, choose RCOSC instead.
NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;


// 32kHz timer period
NRF_RTC0->PRESCALER = 0;

// 30.5ms us compare value, generates EVENTS_COMPARE[0]
NRF_RTC0->CC[0] = 1000;

// Enable EVENTS_COMPARE[0] generation
NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Enabled << RTC_EVTENSET_COMPARE0_Pos;
// Enable IRQ on EVENTS_COMPARE[0]
NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Enabled << RTC_INTENSET_COMPARE0_Pos;

// Enable RTC IRQ and start the RTC
NVIC_EnableIRQ(RTC0_IRQn);
NRF_RTC0->TASKS_START = 1;

// Configure GPIO pin as output with standard drive strength.
NRF_GPIO->PIN_CNF[PIN_LED1] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
(GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
(GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
(GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);

while (1)
{
// __WFE();
if(bLED1Set){
NRF_GPIO->OUTCLR = (1UL << PIN_LED1);
bLED1Set = false;
}else{
NRF_GPIO->OUTSET = (1UL << PIN_LED1);
bLED1Set = true;
}

}
}

// This IRQ handler will trigger every 30.5 ms
void RTC0_IRQHandler(void)
{
volatile uint32_t dummy;
if (NRF_RTC0->EVENTS_COMPARE[0] == 1)
{
NRF_RTC0->EVENTS_COMPARE[0] = 0;

// Increment compare value with 30.5 ms from current time.
NRF_RTC0->CC[0] = NRF_RTC0->COUNTER + 1000;

// Read back event register so ensure we have cleared it before exiting IRQ handler.
dummy = NRF_RTC0->EVENTS_COMPARE[0];
dummy;
}
}

Parents
  • Hi Abir

    If you don't use a SoftDevice I don't know why this code would cause a crash. 

    Can you let me know what kind of hardware you are testing on?

    Is it a standard DK, or some other kind of board?

    If you can upload the entire project that would be great, then I can easily test it here. It should be enough to drag drop a file into your reply if you want to attach files. 

    Best regards
    Torbjørn

  • The board is nrf52-DK, nrf52832, official board
    basic-timer.zip

  • Hi 

    Any project you build in Zephyr will have the Zephyr RTOS running underneath, and this affects how interrupts should be configured. 

    Essentially interrupts in Zephyr can be set up like this:

    IRQ_DIRECT_CONNECT(RTC0_IRQn, 0, my_rtc0_irq_handler, 0);
    irq_enable(RTC0_IRQn);

    More information about the IRQ_CONNECT and IRQ_DIRECT_CONNECT macros can be found here

    Best regards
    Torbjørn

Reply
  • Hi 

    Any project you build in Zephyr will have the Zephyr RTOS running underneath, and this affects how interrupts should be configured. 

    Essentially interrupts in Zephyr can be set up like this:

    IRQ_DIRECT_CONNECT(RTC0_IRQn, 0, my_rtc0_irq_handler, 0);
    irq_enable(RTC0_IRQn);

    More information about the IRQ_CONNECT and IRQ_DIRECT_CONNECT macros can be found here

    Best regards
    Torbjørn

Children
No Data
Related