Author Topic: I2C read inside timer interrupt?  (Read 160 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?