sandeepmistry / arduino-BLEPeripheral

An Arduino library for creating custom BLE peripherals with Nordic Semiconductor's nRF8001 or nR51822.
MIT License
464 stars 180 forks source link

Writing data to Central (BLEserial example) at set interval with timer. #230

Closed DhirajGehlot closed 6 years ago

DhirajGehlot commented 6 years ago

Hello Everyone,

I am using nrf51822, S130 SDK11 with arduino 1.8.1. Currently I am trying to write data (battery data) and toggle led at set interval using timer 2. I am using BLESerial example code to write data. When the timer times out, the BLE kind of crashes and doesn't respond However, if I disable "BLESerial.write(data);" , the led toggles properly and program runs correctly. Somehow, the BLESerial call is causing problem. Is it something that BLESerial function calls and TIMER2 are inter-related? I checked the product specification which mentions TIMER0 is used by softdevice and there is no dependency on TIMER2. Can someone help me out for this issue?

Timer code:
void ms_timer_init(void)
{

    NRF_TIMER2->TASKS_STOP        = 1;                       // Stop timer, if it was running
    NRF_TIMER2->TASKS_CLEAR       = 1;
    NRF_TIMER2->MODE              = TIMER_MODE_MODE_Timer;   // Timer mode (not counter)
    NRF_TIMER2->EVENTS_COMPARE[0] = 0;                       // clean up possible old events
    NRF_TIMER2->EVENTS_COMPARE[1] = 0;
    NRF_TIMER2->EVENTS_COMPARE[2] = 0;
    NRF_TIMER2->EVENTS_COMPARE[3] = 0;

    // Timer is polled, but enable the compare0 interrupt in order to wakeup from CPU sleep
    NRF_TIMER2->INTENSET    = TIMER_INTENSET_COMPARE0_Msk;
    NRF_TIMER2->SHORTS      = 1 << TIMER_SHORTS_COMPARE0_CLEAR_Pos;    // Clear the count every time timer reaches the CCREG0 count
    NRF_TIMER2->PRESCALER   = 9;                                       // Input clock is 16MHz, timer clock = 2 ^ prescale -> interval 1us
    NRF_TIMER2->CC[0]       = 32;                          // 625uS with 1MHz clock to the timer
    NVIC_EnableIRQ(TIMER2_IRQn);
    NRF_TIMER2->TASKS_START = 1;
}

// Start the timer - it will be running continuously}
/** 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
    BLESerial.write(data);
    digitalWrite(LED, !(digitalRead(LED)));
  }
}
Slowspark commented 6 years ago

Welcome, i have similar problem. Timer1 and Timer2 works together to measure frequency, but when i want send data via BLESerial.write(data) counter stop. Any solution for this? Regards

DhirajGehlot commented 6 years ago

Hello,

I got solution to this problem. The issue is cased by running BLE functions from a high priority interrupt. When using a BLE stack such as the S130 SoftDevice interrupt priorities 0 and 2 are reserved for the SoftDevice, and should not be used by the application. Set the interrupt priority of the TIMER2 interrupt to 3, and it should work better: NVIC_SetPriority(TIMER2_IRQn, 3);