sandeepmistry / arduino-nRF5

Arduino Core for Nordic Semiconductor nRF5 based boards
Other
872 stars 278 forks source link

Timer Example Problem #469

Open microderm opened 2 years ago

microderm commented 2 years ago

Hi, I am trying to get some example Timer code working on the nRF52 DK board. This code works when built with Segger IDE but hangs (without printing '*' from the loop) when built from Arduino:

void setup() {
  pinMode(PIN_LED2, OUTPUT);
  pinMode(PIN_LED3, OUTPUT);
  digitalWrite(PIN_LED2, !true);
  digitalWrite(PIN_LED3, !false);
  Serial.begin(250000);
  const int wait = (int)millis() + 2500;
  while (!Serial && (int)(millis()) < wait); // Wait for output //
  Serial.println("*** start ***");

  start_timer();
}

void loop() {
  delay(1000);
  Serial.println("*");
}

void start_timer(void) {
    NRF_TIMER2->MODE = 0;//TIMER_MODE_MODE_Timer;  // Set the timer in Counter Mode
    NRF_TIMER2->TASKS_CLEAR = 1;               // clear the task first to be usable for later
    NRF_TIMER2->PRESCALER = 4;//6;                             //Set prescaler. Higher number gives slower timer. Prescaler = 0 gives 16MHz timer
    NRF_TIMER2->BITMODE = 0;//TIMER_BITMODE_BITMODE_16Bit;     //Set counter to 16 bit resolution
    NRF_TIMER2->CC[0] = 50000;                             //Set value for TIMER2 compare register 0
    NRF_TIMER2->CC[1] = 50;                                 //Set value for TIMER2 compare register 1

    // Enable interrupt on Timer 2, both for CC[0] and CC[1] compare match events
    NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos) | (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
    NVIC_EnableIRQ(TIMER2_IRQn);

    NRF_TIMER2->TASKS_START = 1;               // Start TIMER2
}

/** TIMTER2 peripheral interrupt handler. This interrupt handler is called whenever there it a TIMER2 interrupt
 */
void TIMER2_IRQHandler(void) {
    if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0)) {
        NRF_TIMER2->EVENTS_COMPARE[0] = 0;           //Clear compare register 0 event
        //nrf_gpio_pin_set(GPIO_TOGGLE_PIN);           //Set LED
        //bsp_board_led_on(0);
        digitalWrite(PIN_LED3, !true);
    }

    if ((NRF_TIMER2->EVENTS_COMPARE[1] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0)) {
        NRF_TIMER2->EVENTS_COMPARE[1] = 0;           //Clear compare register 1 event
        //nrf_gpio_pin_clear(GPIO_TOGGLE_PIN);         //Clear LED
        //bsp_board_led_off(0);
        digitalWrite(PIN_LED3, !false);
    }
}

When I comment out the line that sets NRF_TIMER2->INTENSET, the loop continues to print out regular '*' chars, but does not flash the LED on or off.

Any thoughts as to what could be wrong?

microderm commented 2 years ago

Okay, I fixed it. It was some kind of scoping problem. I put the test code in a C file placed within the libraries folder and added #include "nrf52.h" at the top of the file and it worked as expected.

I think the interrupt could not see the TIMER2_IRQHandler and would crash.