Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - frogie

Pages: [1]
1
After doing as much research on the Nordic forums as I could, I think this has something to do with interrupt priority inversion, something along the lines of the PPI internally used by the TWI library having a different interrupt priority if you're using the Soft Device (i.e. when radio is enabled) or not. Sadly I don't really know for sure.

In the meantime, I have gotten around the problem by delegating all my I2C operations to the main loop (using a small message queue of sorts). It means I can't really put anything else inside loop() (like main app logic) since it has to sit there and wait for messages like "Read Accelerator". A small inconvenience but I don't know of a better way right now.

I still would like to know for sure what exactly is going on though!

2
Yes, and they're also used for UART, but if you don't use UART they can be used as GPIOs.
In my setup I only have those pins easily accessible to hook up to a scope (and check whether the main loop() is still running) so that's why I use them.
I also use I2C on specific pins (21, 24), again because of the specific layout of the board I'm working with. Neither of these *should* have any impact though.

3
Bugs / Re: Double restart when programming
« on: August 29, 2017, 06:20:46 PM »
I've noticed the same thing. Not a huge issue, but it annoys me too.
I do know that when you connect to the serial port, it resets the device. Maybe those two things are related?

4
Hi, I've been trying to figure this out: my Simblee freezes while trying to read from an I2C device while inside an interrupt (Timer2 interrupt in this case), but only if I have the radio enabled (with SimbleeBLE.begin()).

If I either:
- do not turn on the radio, or
- read from the device from the main loop(), or
- only perform I2C writes inside the timer interrupt
then the chip doesn't freeze.

The device I'm attempting to read from is an accelerometer (MMA8452Q).
Does anyone have a clue why this could be going on?

Below is my test code. If I comment out the setupBLE() line then I see pin0 toggle. If I instead comment out the setupTimer() line and make calls to readAccel() inside loop() it also works!

Code: [Select]
#include <SimbleeBLE.h>
#include <Wire.h>

#define SCLpin 21
#define SDApin 24

#define TIMER2_PRESCALER (8)
#define TIMER2_RESOLUTION ((1<<TIMER2_PRESCALER)/16) // TimerTick = 16M/2^8 = 16 us
// Note: at 16us per tick, the longest delay that can be requested is roughly 1s

#define READ_ACCEL_INTERVAL (10000) // 10ms
#define READ_ACCEL_TICKS (READ_ACCEL_INTERVAL / TIMER2_RESOLUTION)

#define OUT_X_MSB (0x01) // first register of acceleration data

void readAccel()
{
    digitalWrite(1, HIGH);
    // Read the accelerator values
    byte rawData[6];  // x/y/z accel register data stored here
    Wire.beginTransmission(0x1C); // Address of the Accelerometer
    Wire.write(OUT_X_MSB);
    Wire.endTransmission(false); //endTransmission but keep the connection active
    Wire.requestFrom(0x1C, 6); //Ask for bytes, once done, bus is released by default
    while (Wire.available() < 6); //Hang out until we get the # of bytes we expect
 
    for (int x = 0; x < 6; x++)
      rawData[x] = Wire.read();

    // Here I would convert the 6 bytes into 3 words for x, y and z
    digitalWrite(1, LOW);
}

void timer()
{
    if (NRF_TIMER2->EVENTS_COMPARE[0] != 0)
    {
      // Clear interrupt
      NRF_TIMER2->EVENTS_COMPARE[0] = 0;

      // Update the compare value for next multiple
      NRF_TIMER2->CC[0] += READ_ACCEL_TICKS;

      readAccel();
    }
}

void setupTimer()
{
  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 = TIMER2_PRESCALER; // 16MHz / (2^8) = 16 us resolution
  NRF_TIMER2->CC[0] = READ_ACCEL_TICKS;
  NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
  NVIC_SetPriority(TIMER2_IRQn, 3);
  dynamic_attachInterrupt(TIMER2_IRQn, timer); // Read accelerometer!
  NRF_TIMER2->TASKS_CLEAR = 1; // Clear timer
  NRF_TIMER2->TASKS_START = 1;  // Start TIMER
}

void setupBLE()
{
  // start the BLE stack
  SimbleeBLE.advertisementData = "Test";
  SimbleeBLE.deviceName = "Test";
  SimbleeBLE.txPowerLevel = 0;
  SimbleeBLE.begin();
}

void setup()
{
  // Setup I2C
  Wire.speed = 400;
  Wire.beginOnPins(SCLpin, SDApin);

  // Setup pins for debugging
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);

  setupBLE();
  setupTimer();
}

void loop()
{
  digitalWrite(0, HIGH);
  delay(1);
 
  digitalWrite(0, LOW);
  delay(1);
}


5
BLE and Low Level Development / Re: I2C read inside timer interrupt?
« 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.

Pages: [1]
anything