LowPowerLab Forum

Hardware support => CurrentRanger => Topic started by: pactim on March 26, 2019, 06:21:48 AM

Title: Fastest measure possible?
Post by: pactim on March 26, 2019, 06:21:48 AM
Hi everyone.
I just got the current ranger and need for my tool project to make a very fast current measure. 50kHz if possible.

If have configured my interruption to trigger at 50kHz, it works perfectly, but as soon as I make a readVOUT in the IT handler it goes down to 40Hz, can't seem to get higher frequency.
Is there any way to increase the actual current measure frequency.

My setup function if this can helps ;)
Code: [Select]
void setup() {
  SerialUSB.begin(1); //USB hyper speed, baud wont matter
/*
  //some buzz
  tone(BUZZER, NOTE_C5); delay(100);
  tone(BUZZER, NOTE_E5); delay(100);
  tone(BUZZER, NOTE_G5); delay(100);
  tone(BUZZER, NOTE_C6); delay(200);
  noTone(BUZZER);        delay(50);
  tone(BUZZER, NOTE_G5); delay(100);
  tone(BUZZER, NOTE_C6); delay(400);
  noTone(BUZZER);
*/
#ifdef OLED_EN
  Wire.begin();
  Wire.beginTransmission(OLED_ADDRESS);
  byte error = Wire.endTransmission();
  if (error == 0)
  {
    SerialUSB.print("OLED FOUND at "); SerialUSB.println(OLED_ADDRESS);
    u8g2.begin();
    //u8g2.setDisplayRotation(U8G2_R2); //if required (inside/custom mount?)
    u8g2.setBusClock(1000000); //1Mhz i2C clock
    OLED_found = true;
  }
  else SerialUSB.println("NO OLED attached...");
#endif

  pinMode(A0, OUTPUT); //DAC/GNDISO
  pinMode(SENSE_OUTPUT, INPUT);
  pinMode(SENSE_GNDISO, INPUT); //GND-ISO
  pinMode(SENSE_VIN, INPUT); //VIN > 1MEG > SENSE_VIN > 2MEG > GND
  pinMode(AUTOFF, INPUT_PULLUP);
  pinMode(OFFSET_LED, OUTPUT);
  pinMode(LPFLED, OUTPUT); //STATUS/LPF-LED
  pinMode(LPFPIN, OUTPUT); //LPF control pin
  pinMode(BUZZER, OUTPUT);
  pinMode(MA,OUTPUT);
  pinMode(UA,OUTPUT);
  pinMode(NA,OUTPUT);

  qt[0].begin(); qt[1].begin(); qt[2].begin(); //touch pads
  analogReadResolution(12);
  analogWriteResolution(10);  //DAC resolution

  //DAC->CTRLA.bit.RUNSTDBY = 0x01;delay(1);
  //DAC->CTRLB.bit.REFSEL=0;//pick internal reference, skip SYNCDAC (done by analogWrite)
  analogWrite(A0, DAC_GND_ISO_OFFSET);  // Initialize Dac to OFFSET

#ifdef ADC_CALIBRATE_EN
  #ifndef ADC_CALIBRATE_FORCED
    adcCorrectionCheck();
  #else
    //or hardcoded:
    analogReadCorrectionForced(ADC_CALIBRATE_FORCED_OFFSET, ADC_CALIBRATE_FORCED_GAIN);
      //(offset, gain) - gain is 12 bit number (1 bit integer + 11bit fractional, see DS p895)
      //               - offset is 12bit 2s complement format (p896)
  #endif

  if (OLED_found && !calibrationPerformed && MA_PRESSED)
  {
    u8g2.clearBuffer();
    SerialUSB.println("ADC calib. values:");
    SerialUSB.print("Offset="); SerialUSB.println(offsetCorrectionValue);
    SerialUSB.print("Gain="); SerialUSB.println(gainCorrectionValue);
    u8g2.setFont(u8g2_font_9x15B_tf);
    u8g2.setCursor(0,28); u8g2.print("ADC CALIB:");
    u8g2.setCursor(0,40); u8g2.print("offset:");
    u8g2.setCursor(64,40); u8g2.print(offsetCorrectionValue);
    u8g2.setCursor(0,54); u8g2.print("gain  :");
    u8g2.setCursor(64,54); u8g2.print(gainCorrectionValue);
    u8g2.sendBuffer();
    delay(2000);
  }
#endif

  //BT check
  Serial.begin(SERIALBAUD);
  SerialUSB.print("Bluetooth AT check @");SerialUSB.print(SERIALBAUD);SerialUSB.print("baud...");
  Serial.print("AT"); //assuming HC-06, no line ending required
  uint32_t timer=millis();
  while(millis()-timer<5000) //about 1s to respond
  {
    if (Serial.available()==2 && Serial.read()=='O' && Serial.read()=='K')
    {
      BT_found=true;
      break;
    }
  }
  SerialUSB.print(BT_found?"OK!":"no response.");

  //rangeMA(); //done in bootloader
  //cgo WDTset();

  tcConfigure(sampleRate); //sample rate argument no longer needed
  //tcDisable();
  tcStartCounter(); //starts the timer

/*
  // ADC Linearity/Bias Calibration from NVM (should already be done done in core)
  uint32_t bias = (*((uint32_t *) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos;
  uint32_t linearity = (*((uint32_t *) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
  linearity |= ((*((uint32_t *) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
  ADC->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | ADC_CALIB_LINEARITY_CAL(linearity);
*/
}

and the configure
Code: [Select]
 void tcConfigure(int aSampleRate)
{
 // Enable GCLK for TCC2 and TC5 (timer counter input clock)
 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
 while (GCLK->STATUS.bit.SYNCBUSY);

 tcReset(); //reset TC5

 // Set Timer counter Mode to 16 bits
 TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
 // Set TC5 mode as match frequency
 TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
 //set prescaler and enable TC5
 TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV64 | TC_CTRLA_ENABLE;
 //set TC5 timer counter based off of the system clock and the user defined sample rate or waveform

 // TC5->COUNT16.CC[0].reg = (uint16_t) ((SystemCoreClock / aSampleRate) - 1);
 TC5->COUNT16.CC[0].reg = 15;
 while (tcIsSyncing());

 // Configure interrupt request
 NVIC_DisableIRQ(TC5_IRQn);
 NVIC_ClearPendingIRQ(TC5_IRQn);
 NVIC_SetPriority(TC5_IRQn, 0);
 NVIC_EnableIRQ(TC5_IRQn);

 // Enable the TC5 interrupt request
 TC5->COUNT16.INTENSET.bit.MC0 = 1;
 while (tcIsSyncing()); //wait until TC5 is done syncing
}

Cheers