ATTinyCore icon indicating copy to clipboard operation
ATTinyCore copied to clipboard

Add sketch for tuning the internal oscillator

Open aster94 opened this issue 7 years ago • 24 comments

hello,

i found in pins_arduino.h that there is the possibility to tune the internal oscillator with a sketch I wasn't able to find this sketch, maybe had it been removed from the repo for error?

aster94 avatar May 29 '17 15:05 aster94

It predates my maintaining the repo. I have no sketch for tuning the internal oscillator.

On May 29, 2017 11:12 AM, "aster94" [email protected] wrote:

hello,

i found in pins_arduino.h that there is the possibility to tune the internal oscillator with a sketch I wasn't able to find this sketch, maybe had it been removed from the repo for error?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/139, or mute the thread https://github.com/notifications/unsubscribe-auth/AGdyW4kDjDhOoQBy_DgGqFWSjLcOqfHxks5r-uBYgaJpZM4Npari .

SpenceKonde avatar May 29 '17 15:05 SpenceKonde

Ok, it was just curiosity since it was written there. Anyway online is possible to find a few solutions. You could close!

aster94 avatar May 30 '17 01:05 aster94

Reopening so we have a place to discuss the lack of a tuning sketch.

Key issues include:

  • How do we want to do the tuning? Some of them use serial for that. Why couldn't we use blink? Ie, you load the tuner sketch, connect it to the blink pin of a working arduino, do a sanity check on the measured length of the pulses, and then (assuming it checks out) we fiddle with OSCCAL until the length of the blink comes out to 1000ms?
  • How do we store/report the magic value when the memory gets wiped when a new sketch is uploaded?

SpenceKonde avatar May 31 '17 16:05 SpenceKonde

i would suggest to add two sketches:

the simpler version for the less inclined user which uses the serial. it would be harder to create but even an unexperienced person could simply use it

and the other version as you suggested using another board (or better an oscilloscope) to fine tuning the register

about how to store the value i would suggest to: -use the EEPROM -say to put OSCCAL = 0x__ at the begin of every sketch -say to change the value in the pins_arduino.h

every solution has pro and con

aster94 avatar May 31 '17 21:05 aster94

hello Dr.Azzy,

try this: `#define pot PA0 //#define LA

void setup() {

Serial.begin(115200);

//OSCCAL = 0x00; Serial.print("Osccal= "); Serial.println(OSCCAL, HEX);

pinMode(pot, INPUT);

#ifdef LA //for logic analizer pinMode(5, OUTPUT); noInterrupts(); TCNT1 = 0; TCCR1A = 0; TCCR1B = 0; TCCR1B |= (1 << WGM12); //Start timer 1 in CTC mode Table 14.4 TCCR1A |= (1 << COM1B0); //Timer1 in toggle mode Table 14-1 TCCR1B |= (1 << CS10) ; //prescaler Table 14-5, no prescal interrupts(); OCR1A = 3; //CTC Compare value #endif }

void loop() { int val = analogRead(pot);

OSCCAL = val / 4;

Serial.println("I'am a nice working sketch that help you to tune your internal oscillator");

Serial.print("OSCCAL:\t"); Serial.println(OSCCAL, HEX);

delay(50); }`

i found it on google and adapted to make it simplier

aster94 avatar Jun 27 '17 15:06 aster94

This library works for me: https://github.com/Coding-Badly/TinyTuner2 Requires this library: https://github.com/Coding-Badly/TinyDebugKnockBang And works with this ISP sketch: https://github.com/Coding-Badly/TinyISP

JChristensen avatar Feb 02 '18 01:02 JChristensen

Here's a nicer version of the pot+serial method. It avoids sudden jumps in frequency. It also prints the "high" or "low" strings to remind the user that OSCCAL is not continuous. I'm posting this here as a reminder as I don't have time ATM to finish this. Instructions need to be written, and I haven't yet decided what's the best way to output pulses for more precise calibration. Right now, I'm leaning towards simply enabling the CKOUT fuse through a menu entry (like LTO), but I need to learn how to make the menu.

// TODO: CKOUT

const byte potentiometerPin = A2;  // Pick any analog pin.

void setup() {
  Serial.begin(115200);
}

void loop() {
  delay(100);
  byte val = analogRead(potentiometerPin) / 4;
  const byte osccal = OSCCAL;

  // Prevent large jumps in frequency by slowly slewing.
  if (osccal != val) {
    val = val > osccal ? osccal + 1 : osccal - 1;
  }
  OSCCAL = val;

  Serial.print(F("A longish string to test serial IO. OSCCAL value: "));
  Serial.print((int)(val));
  if (val > 127) {
    Serial.println(F(" high."));
  } else {
    Serial.println(F(" low."));
  }
}

exzombie avatar May 12 '18 11:05 exzombie

Another example of calibration is V-USB project for Attiny: by: Project: EasyLogger Author: Christian Starkjohann Creation Date: 2006-04-23

/* ------------------------------------------------------------------------- */
/* ------------------------ Oscillator Calibration ------------------------- */
/* ------------------------------------------------------------------------- */

/* Calibrate the RC oscillator to 8.25 MHz. The core clock of 16.5 MHz is
 * derived from the 66 MHz peripheral clock by dividing. Our timing reference
 * is the Start Of Frame signal (a single SE0 bit) available immediately after
 * a USB RESET. We first do a binary search for the OSCCAL value and then
 * optimize this value with a neighboorhod search.
 * This algorithm may also be used to calibrate the RC oscillator directly to
 * 12 MHz (no PLL involved, can therefore be used on almost ALL AVRs), but this
 * is wide outside the spec for the OSCCAL value and the required precision for
 * the 12 MHz clock! Use the RC oscillator calibrated to 12 MHz for
 * experimental purposes only!
 */
static void calibrateOscillator(void)
{
uchar       step = 128;
uchar       trialValue = 0, optimumValue;
int         x, optimumDev, targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);

    /* do a binary search: */
    do{
        OSCCAL = trialValue + step;
        x = usbMeasureFrameLength();    /* proportional to current real frequency */
        if(x < targetValue)             /* frequency still too low */
            trialValue += step;
        step >>= 1;
    }while(step > 0);
    /* We have a precision of +/- 1 for optimum OSCCAL here */
    /* now do a neighborhood search for optimum value */
    optimumValue = trialValue;
    optimumDev = x; /* this is certainly far away from optimum */
    for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){
        x = usbMeasureFrameLength() - targetValue;
        if(x < 0)
            x = -x;
        if(x < optimumDev){
            optimumDev = x;
            optimumValue = OSCCAL;
        }
    }
    OSCCAL = optimumValue;
}
/*
Note: This calibration algorithm may try OSCCAL values of up to 192 even if
the optimum value is far below 192. It may therefore exceed the allowed clock
frequency of the CPU in low voltage designs!
You may replace this search algorithm with any other algorithm you like if
you have additional constraints such as a maximum CPU clock.
For version 5.x RC oscillators (those with a split range of 2x128 steps, e.g.
ATTiny25, ATTiny45, ATTiny85), it may be useful to search for the optimum in
both regions.
*/

void    usbEventResetReady(void)
{
    /* Disable interrupts during oscillator calibration since
     * usbMeasureFrameLength() counts CPU cycles.
     */
    cli();
    calibrateOscillator();
    sei();
    eeprom_write_byte(0, OSCCAL);   /* store the calibrated value in EEPROM */
}

dontsovcmc avatar Jun 13 '18 22:06 dontsovcmc

Hi, I have an idea how to calibrate Internal oscillator easily:

Script steps:

  • PC uploads calibration program to chip it sends 1 byte to UART every X "sec"
  • PC measures time between bytes from com-port
  • send commands 'high', 'low' to chip to change period of receiving bytes from chip.
  • send command 'show OSCCAL' to chip
  • chip sends new value of OSCCAL to Script
  • PC uploads you program with define 'NEW_OSCCAL' in code.

problems I see: UART speed can be incorrect cause no calibration. We should change OSCCAL automatically and stop when receive command from PC 'i hear your'.

dontsovcmc avatar Sep 23 '18 14:09 dontsovcmc

Deferring to 1.2.1, so we can play around with the new bootloaders for these parts and decide how to proceed. The vast majority of attiny chips happens to be on target at 3.3~5v at room temperature, making this functionality less critical for the simple case. It is still planned for a future version, but I want to get these new bootloaders into the hands of users.

SpenceKonde avatar Oct 08 '18 18:10 SpenceKonde

@SpenceKonde Are you still interested on this? I may not be able to do it myself but I was planning to ask someone I know to do it for me. I'm working with 841 at 9600 through an RS485 and sometimes I get broken messages with some parts correct and random symbols on other parts.

It may be something related with the RS485 but I'd like to rule this one out. Let me know and I'll propose this to the guys I know.

Thanks!

tatobari avatar Nov 09 '18 19:11 tatobari

I still have interest in this, though the more i learn, the less optimistic i get. The main issue is that, if the frequency is in fact pretty much on target at room temp and typical opperating voltage (apparently the case on all except x41, 828, 1634), the main thing that impacts the speed is the temperature. So it needs to be calibrated at the target temperature. This is awkward, particularly if the device will be exposed to varying temperatures...

With the exceptions mentioned above, the temperature dependence is much smaller, but it depends strongly on voltage, with a "knee" in the voltage-speed curve around 4v. In an uncalibrated chip, this means that when running off lithium ion batteries, it will work except when the batteries are fully charged.... but this also suggests that calibration heuristics could be used in place of true calibration. And that a battery opperated device could even run a sketch that monitored the voltage and used it to adaptively adjust osccal as the voltage changed.

Both cases may end up needing different cal for bootloader and application

But, the bottom line is that im pessimistic about a one-size-fits-all approach here, since the "common case" doesnt seem to require it

In your specific case, is the problem voltage dependent? What voltage are the parts running at?


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore: Arduino support for almost every ATTiny microcontroller Contact: [email protected]

On Fri, Nov 9, 2018, 14:35 tatobari <[email protected] wrote:

@SpenceKonde https://github.com/SpenceKonde Are you still interested on this? I may not be able to do it myself but I was planning to hire someone to do it for me. I'm working with 841 at 9600 through an RS485 and sometimes I get broken messages with some parts correct and random symbols on other parts.

It may be something related with the RS485 but I'd like to rule this one out. Let me know and I'll propose this to the guys I know.

Thanks!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/139#issuecomment-437471117, or mute the thread https://github.com/notifications/unsubscribe-auth/AGdyW8JiBfnA0UHufvcbxZ3ACOhlx5Tnks5utdkSgaJpZM4Npari .

SpenceKonde avatar Nov 09 '18 20:11 SpenceKonde

Sorry it took me so long to test this, I had to solder some stuff becauseI had all working with 5V. I managed to switch to 3.3V and the problems disappeared. My only issue now is that most of my system works at 5V because there are a few pieces which I coudn't find for 3.3V. I'll see what I can do about this.

Anyway, my offer is still on for any improvements on this issue though there doesn't seem to be much to do here. Let me know!

Thanks!

tatobari avatar Nov 09 '18 22:11 tatobari

I think in your case, there may be a much simpler solution - at the start of your sketch (in setup() ), try doing: NoInterrupts(); OSCCAL0=OSCCAL0-12; Interrupts();

(and running it at 5v). Unlike most AVRs, the OSCCAL0 curve is pretty much linear over the entire range of values (most AVR's have a step-change in the middle)

Let me know how/if that works. I'd been hoping to try it myself this weekend, but ran out of time.

-Spence

On Fri, Nov 9, 2018 at 5:44 PM tatobari [email protected] wrote:

Sorry it took me so long to test this. I had to solder some stuff, I had all working with 5V. I managed to switch to 3.3V and the problems dissapeared. My only issue now is that most of my system works at 5V because there are a few pieces which I coudn't find for 3.3V.

Anyway, my offer is still on for any improvements on this issue, though there doesn't seem to be much to do here. Thanks!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/139#issuecomment-437518567, or mute the thread https://github.com/notifications/unsubscribe-auth/AGdyW-ZWnY5g76N7ANRMYD6bMNLW659fks5utgVDgaJpZM4Npari .

--


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore: Arduino support for almost every ATTiny microcontroller Contact: [email protected]

SpenceKonde avatar Nov 13 '18 06:11 SpenceKonde

I've been working with OSCCAL on some ATtiny13 with terrible internal oscillators (both were off by about an MHz). After implementing a nice and efficient software serial library for the T13 I've been using sleemanj's OSCCAL_helper sketch. It will need some minor adjustments, but It lets your tune the oscillator by watching your serial monitor and/or watching the on/off time from a timer output. The result is a simple sketch that "just works".

MCUdude avatar Dec 13 '19 22:12 MCUdude

I have a very nice solution for calibrating OSCCAL working on the ATtiny13. All the brilliant stuff was done by @nerdralph, and I just tweaked the code a little.

All you do is just load upload the sketch, select the correct baud rate in the serial monitor and repeatedly send x characters. The ATtiny measures the received pulse and tunes it's own OSCCAL register until it's within 1%. When the value is stable it's automatically stored in EEPROM added 0, and the sketch is halted.

Super simple for the end-user to accomplish, and no extra hardware except for a USB to serial adapter is needed. I'm sure this could rather easily be adapted to work with ATtinyCore as well. It's at least worth a look!

MCUdude avatar Dec 22 '19 23:12 MCUdude

I am working on a similar solution myself :-) It will be based on sending a different character, but is otherwise very similar; I will use different solution for storage of the calibration data depending on whether Optiboot is in use (will come with a big Optiboot update too to fix the nasty, nasty optiboot bug.

SpenceKonde avatar Sep 20 '20 22:09 SpenceKonde

will come with a big Optiboot update too to fix the nasty, nasty optiboot bug.

What nasty Optiboot bug?

MCUdude avatar Sep 21 '20 16:09 MCUdude

Have you looked at picoboot yet? It should be a drop-in for optiboot, but with a higher baud rate, less flash usage (320B + 2B for the virtual reset vector), and automatic OSCCAL calibration so you don't have to write another tuner program. https://github.com/nerdralph/picoboot-lib

p.s. and the top-down flash erase that you wanted for Optiboot.

nerdralph avatar Sep 21 '20 16:09 nerdralph

Missed the replies above: The nasty bug with virtual boot and poorly timed (BOD?) reset leaving it with first page erased so neither bootloader nor app runs, fix is to always erase all the flash starting from the highest page when told to do anything that would cause it to erase the first page (and to not erase anything otherwise, because it will have already erased it) #398.

Picoboot is cool and the advantages are really compelling on these parts, where you really want that extra flash space - haven't played with it yet, sadly (and only briefly worked on the OSCCAL thing above before deciding that I should really focus on more pressing issues). But if it only supports some parts, there's still going to be a need for Optiboot for the rest of them. My solution was also going to determine at least one other cal value (and that probably isn't possible with the autobaud approach): 16 MHz for the 841 (lol, yup, you heard that right. Their oscillator is highly linear - no discontinuity at 0x80 - and goes up really high), and 12 MHz for the 1634 and 828 (which has similar oscillator, but with shallower slope).

SpenceKonde avatar Nov 09 '20 07:11 SpenceKonde

Do you have any stats on which MCUs are the most popular for ATTinyCore? The new picoboot supports the tx5, tx4, and tx8, which I think should cover the vast majority of users. I'd consider adding support for other targets if they are readily available and at least somewhat popular. p.s. to make it a bit easier to try out picoboot, I've added builds for t84 and t85.

nerdralph avatar Nov 10 '20 22:11 nerdralph

Stats? No - but based on volume of questions and issues, as well as tindie sales, people love the 841 (who can blame them?!), that and the 85 look like the most popular ones, It has hardware uart too, though nobody will know if you use it ;) - and factory cal is consistently wrong at 5v - its significantly over speed, like 4%, so huge interest in auto cal solution. 1634 as well. Not sure if 84 or 1634 is in 3rd place (but everything else is much less popular than those 4) 1634 has the same wrong factory cal (but you cant crank it up to 16). Both also have the "4 page erase" (erase on 841 same size as 84, but for write, the page is 1/4th the size. Pages on the 1634 are 2x size of 841 iirc). Oh, and both of those have a separate PUEx register for each port to control pullups. It's in low IO space on 1634, but not 841 (sigh)


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore: Arduino support for almost every ATTiny microcontroller Contact: [email protected]

On Tue, Nov 10, 2020, 17:23 Ralph Doncaster [email protected] wrote:

Do you have any stats on which MCUs are the most popular for ATTinyCore? The new picoboot supports the tx5, tx4, and tx8, which I think should cover the vast majority of users. I'd consider adding support for other targets if they are readily available and at least somewhat popular. p.s. to make it a bit easier to try out picoboot, I've added builds for t84 and t85.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/139#issuecomment-725003651, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTXEW7GPNZMQVAKZRQZY3TSPG4PPANCNFSM4DNFVLRA .

SpenceKonde avatar Nov 10 '20 22:11 SpenceKonde

I looked at the t841 datasheet, and in addition to the funky way of writing to flash, it also has a different OSCCAL register. So supporting it looks like it would require writing separate versions of the OSCCAL tuning and the flash writing routines. I could probably add support for the t2313 & t4313, but does anyone really want to use a bootloader on them?

On Tue, Nov 10, 2020 at 6:46 PM Spence Konde (aka Dr. Azzy) < [email protected]> wrote:

Stats? No - but based on volume of questions and issues, as well as tindie sales, people love the 841 (who can blame them?!), that and the 85 look like the most popular ones, It has hardware uart too, though nobody will know if you use it ;) - and factory cal is consistently wrong at 5v - its significantly over speed, like 4%, so huge interest in auto cal solution. 1634 as well. Not sure if 84 or 1634 is in 3rd place (but everything else is much less popular than those 4) 1634 has the same wrong factory cal (but you cant crank it up to 16). Both also have the "4 page erase" (erase on 841 same size as 84, but for write, the page is 1/4th the size. Pages on the 1634 are 2x size of 841 iirc). Oh, and both of those have a separate PUEx register for each port to control pullups. It's in low IO space on 1634, but not 841 (sigh)


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore: Arduino support for almost every ATTiny microcontroller Contact: [email protected]

On Tue, Nov 10, 2020, 17:23 Ralph Doncaster [email protected] wrote:

Do you have any stats on which MCUs are the most popular for ATTinyCore? The new picoboot supports the tx5, tx4, and tx8, which I think should cover the vast majority of users. I'd consider adding support for other targets if they are readily available and at least somewhat popular. p.s. to make it a bit easier to try out picoboot, I've added builds for t84 and t85.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub < https://github.com/SpenceKonde/ATTinyCore/issues/139#issuecomment-725003651 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/ABTXEW7GPNZMQVAKZRQZY3TSPG4PPANCNFSM4DNFVLRA

.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/139#issuecomment-725013142, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKNZ6UQYB4WXC4QEURTCTLSPG7D5ANCNFSM4DNFVLRA .

nerdralph avatar Nov 12 '20 00:11 nerdralph

Well, yes, it's a different OSCCAL register, But yeah - the 841 and 85 are hands down, no contest, the most popular parts. After that it's either the 1634 (which is like the 841) or 84. Far below those, the 4313 has a surprising number of users, but I don't offer optiboot on it and I don';t feel a particular need to put any bootloader on it - frankly, I try to discourage people from using those terrible parts at all! The x61's are also an option, I guess... Despite the fact that they're available in DIP, everyone seems to have the good sense not to use them... they're kinda like the 85, with the wacky timer, PLL and that shit... but lik . I think their main role will be with micronucleus as another 16.5 MHz from internal PLL part like the 85 of the original digispark - I have that board ready, though I haven't built and tried micronucleus on it yet (I think it's a drop-in though - basically an exact copy of the '85 config except different pins).... I've got 3 micronucleus prototypes, 4 pcs each. just waiting to get flashed and then ready to rock and roll... an 841, 861, and 1634 - plus a 1614, but that needs a bit more work...

As for which parts people generally want to use serial bootloaders on, the 841 and 1634 are very popular, since people usually have a serial port hooked up to them anyway, and are using them because of the hardware serial. Everything else much less so, though I suspect the calibration situation doesn't help that... on the 841, it was particularly bad until my recent hackjob that nudges the cal down by a fixed amout, and with that, UART will generally work at the baud we use between 3.3~5v.... like, people would just use crystals on them to make the UART work...

SpenceKonde avatar Nov 12 '20 02:11 SpenceKonde