Author Topic: I2C read inside timer interrupt?  (Read 359 times)

andrey_dung

  • RFduino Newbie
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
I2C read inside timer interrupt?
« on: June 03, 2017, 10:44:41 AM »
It seems that I2C read is not allowed in the interrupt handler of RFduino. Is there any solution to this?

Code: [Select]
#include <Wire.h>
#include <Adafruit_VCNL4010.h>
#include <SPI.h>
#include <SD.h>
#include <RFduinoBLE.h>


// Proximity sensor
Adafruit_VCNL4010 vcnl;
uint16_t proximity;
uint16_t ambientLight;

char buffer[12];

#define CHIPSELECT 2
uint_fast16_t volatile number_of_ms = 2;     // ms

void timer_config(void)
{
  NRF_TIMER2->TASKS_STOP = 1;  // Stop timer
  NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;  // taken from Nordic dev zone
  NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
  NRF_TIMER2->PRESCALER = 9;  // 32us resolution
  NRF_TIMER2->TASKS_CLEAR = 1; // Clear timer
  // With 32 us ticks, we need to multiply by 31.25 to get milliseconds
  NRF_TIMER2->CC[0] = number_of_ms * 31;
  NRF_TIMER2->CC[0] += number_of_ms / 4;
  NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;  // taken from Nordic dev zone
  NRF_TIMER2->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
  attachInterrupt(TIMER2_IRQn, TIMER2_Interrupt);    // also used in variant.cpp to configure the RTC1
  NRF_TIMER2->TASKS_START = 1;  // Start TIMER
}

bool transmitFlag = 0;

void setup() { 
  // BLE stack
  RFduinoBLE.deviceName = "andrey";
  RFduinoBLE.begin();

  // start SD card
  pinMode(CHIPSELECT, OUTPUT);
  if (!SD.begin(CHIPSELECT)) {
    return;
  }

  timer_config();

  if (!vcnl.begin()) {
    return;
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  if (transmitFlag) {
    transmitFlag = 0;
   
    proximity = vcnl.readProximity();
    ambientLight = vcnl.readAmbient();

    File myFile = SD.open("datafile.csv",  FILE_WRITE);
    if (myFile) {
      myFile.print(buffer);
      myFile.close();
    }
  }   
}

void TIMER2_Interrupt(void) {
  if (NRF_TIMER2->EVENTS_COMPARE[0] != 0) {
    transmitFlag = 1;
//    proximity = vcnl.readProximity();
//    ambientLight = vcnl.readAmbient();

    sprintf(buffer, "%5d5d\n", 12, proximity, ambientLight);
   
    NRF_TIMER2->EVENTS_COMPARE[0] = 0;
  }
}

As soon as I uncommented vcnl.readProximity or vcnl.readAmbient inside the interrupt handler, BLE doesn't work.

How could I resolve this?

frogie

  • RFduino Newbie
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: I2C read inside timer interrupt?
« Reply #1 on: August 28, 2017, 11:13:54 AM »
Hi! Did you ever figure this out? I am having (I think) a similar issue. More specifically: Writes from interrupt work fine. Reads do not.
If I disable BLE, both reads and writes work fine. The weirdest part is that calling the exact same read or write methods from loop() works just fine, even with BLE enabled.

 

anything