How to use timer to execute a function every x micro seconds? Arduino DUE

Hey guys,

I have been using MPU9255 to give me angles and So I finally managed to get it working from a tutorial in youtube.

the code as follows:

void setup()
{
  Wire.begin();
  //initialise the clock speed, gyroscope, accel,
  accelgyro.initialize();
  //serial communication begin
  for(int i = 0; i < 2000; i++)
  {
    get_gyro();
    G_cal_x += Gxyz[0];
    G_cal_y += Gxyz[1];
    G_cal_z += Gxyz[2];
    delay(3);
  }
  G_cal_x /= 2000;
  G_cal_y /= 2000;
  G_cal_z /= 2000;
  Serial.begin(115200);
  // TimerStart(TC1, 0,TC3_IRQn, 8000);
  looper = micros();
}
void loop()
{
  // Serial.println("print raw gyro");
  get_gyro();
  Gxyz[0] = Gxyz[0] - G_cal_x;
  Gxyz[1] = Gxyz[1] - G_cal_y;
  angle_x += Gxyz[0]*0.000000954;
  angle_y += Gxyz[1]*0.000000954;

  d_angle_x = angle_x*180;
  d_angle_y = angle_y*180;
  Serial.print(d_angle_x);
  Serial.print(" ");
  Serial.println(d_angle_y);
  // attaching interrupt so the angle_x will be updated every 125 us

  while((micros()-looper) < 125)
  {
    looper = micros();
  }
}

however now I want to use timer to call the function to read data from MPU9255 every 125us. According to the datasheet of MPU9255 it samples gyro data every 8000hz so 125us by default. I have tried implementing timer into the due

void setup()
{
  Wire.begin();
  //initialise the clock speed, gyroscope, accel,
  accelgyro.initialize();
  //serial communication begin
  for(int i = 0; i < 2000; i++)
  {
    get_gyro();
    G_cal_x += Gxyz[0];
    G_cal_y += Gxyz[1];
    G_cal_z += Gxyz[2];
    delay(3);
  }
  G_cal_x /= 2000;
  G_cal_y /= 2000;
  G_cal_z /= 2000;
  Serial.begin(115200);
  TimerStart(TC1, 0,TC3_IRQn, 8000);
  // looper = micros();
}



void loop()
{
  // Serial.println("print raw gyro");
  // get_gyro();
  // Gxyz[0] = Gxyz[0] - G_cal_x;
  // Gxyz[1] = Gxyz[1] - G_cal_y;
  // angle_x += Gxyz[0]*0.000000954;
  // angle_y += Gxyz[1]*0.000000954;

  d_angle_x = angle_x*180;
  d_angle_y = angle_y*180;
  Serial.print(d_angle_x);
  Serial.print(" ");
  Serial.println(d_angle_y);
  // attaching interrupt so the angle_x will be updated every 125 us

  // while((micros()-looper) < 125)
  // {
  //   looper = micros();
  // }
}

//initialising or getting the gyro data
void get_gyro()
{
  accelgyro.getMotion9(&ax,&ay,&az,&gx,&gy,&gz,&mx,&my,&mz);
  Gxyz[0] = gx;
  Gxyz[1] = gy;
  Gxyz[2] = gz;
}

void TC3_Handler()
{
  TC_GetStatus(TC1, 0);
  get_gyro();
  Gxyz[0] = Gxyz[0] - G_cal_x;
  Gxyz[1] = Gxyz[1] - G_cal_y;
  angle_x += Gxyz[0]*0.000000954;
  angle_y += Gxyz[1]*0.000000954;
}
//
void TimerStart(Tc *tc, uint32_t channel, IRQn_Type irq,uint32_t freq)
{
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(irq);
  TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
  uint32_t rc = VARIANT_MCK/128/freq;
  TC_SetRA(tc, channel, rc >> 1);
  TC_SetRC(tc, channel, rc);
  TC_Start(tc, channel);
  tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPCS | TC_IER_CPAS;
  tc->TC_CHANNEL[channel].TC_IDR =~(TC_IER_CPCS | TC_IER_CPAS);
  NVIC_EnableIRQ(irq);
}

This doesn’t give me the right values or give me any values at all. Also I would be grateful if some one can point me right direction to using Arduino due timers I don’t want to use the libraries by others I understand the code but I know there are external function in due I have read some parts of the datasheet but it is just huge and I have read some of the ASF as well however I still feel unsatisfied by it and would like to know more and would be grateful for a easier tutorial.

Here is an example of a Timer Counter programmed to produce an interrupt every 1/8000 second. I used Timer Counter 0 channel 2 (TC2):

volatile boolean Flag = false;

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(250000);

  tc_setup();
}

void loop()
{

  if (Flag == true) {

    Blink();
    Flag = false;
  }
}

void Blink (){

  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

}

/*************  Timer Counter 0 Channel 2 to generate interrupts every 1/8000 second  ************/

void tc_setup() {

  PMC->PMC_PCER0 |= PMC_PCER0_PID29;                      // TC2 power ON : Timer Counter 0 channel 2 IS TC2
  TC0->TC_CHANNEL[2].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1  // MCK/2, clk on rising edge --> F = 42 MHz
                              | TC_CMR_WAVE               // Waveform mode
                              | TC_CMR_WAVSEL_UP_RC;       // UP mode with automatic trigger on RC Compare
                      

  TC0->TC_CHANNEL[2].TC_RC = 5250;  //<*********************  Frequency = (Mck/2)/TC_RC  Hz = 8000 Hz

  TC0->TC_CHANNEL[2].TC_IER = TC_IER_CPCS;    // Interrupt enable on RC compare match
 // TC0->TC_CHANNEL[2].TC_IDR = ~TC_IER_CPCS; // IDR = interrupt disable register
  NVIC_EnableIRQ(TC2_IRQn);      // Enable TC2 interrupts

  TC0->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Reset TC2 counter and enable

}

void TC2_Handler () {
  
  TC0->TC_CHANNEL[2].TC_SR;  // Clear status register

  Flag = true;
}