ATtiny internal oscillator calibration - Page 1
Forum section: electronics / general

author: HwAoRrDk
author_rank: Super Contributor
timestamp: August 10, 2017, 07:54:28 pm
content: I seem to be facing several timing-related issues this week...I had soldered a brand-new ATtiny841 on a board, and as a quick check that it was functioning correctly, I programmed it with a short program that would just repeatedly send "Hello world" out the serial UART at 9600 baud. However, when I connected with my terminal program, the data coming in was garbled! Double-checked all my code and the baud rate in the terminal settings, but everything appeared to be correct. So I got out the logic analyser, and some captures revealed that the only thing wrong was that the baud rate was not what I expected: approx. 10kbaud - too fast!Then I remembered reading somewhere that the factory calibration for the internal oscillator of ATtiny chips is for 3V, and when running at 5V, the clock speed will be a bit off. I enabled the CLKOUT fuse, and took another capture of the clock signal with the logic analyser (probably not the most precise of measuring tools, but sampling at 25Msps should be good enough, right?). Turns out my ATtiny841 was running at 8.34MHz!That is quite a way out. In fact, comparing to the frequency vs operating voltage graph in the datasheet, it's above even what that suggest is the norm for 5V operation.Anyway, I managed to correct the clock speed with some trial-and-error tweaking of the OSCCAL0 register (-8 got me to 7.99MHz). My question is, how do I go about making this a permanent adjustment? I've not investigated doing this before.I see from Atmel Studio's programming tool that it has a facility to set a calibration for the internal oscillator, but it confuses me a bit. It asks for a value and an address, then whether to program either flash or EEPROM. For the value, do I just use the absolute value of my tweak to the OSCCAL0 register? But about the address? I gather the factory oscillator calibration values are in the device signature data, but I don't know the right address or even whether it's in flash or EEPROM. Any help or pointers appreciated.

author: Geoff_S
author_rank: Regular Contributor
timestamp: August 10, 2017, 08:54:09 pm
content: If your actual baud rate was more than double what you expected, then I doubt it is simply an osc cal issue. I'd double check either your baud rate register settings, and/or your clock configuration.

author: sokoloff
author_rank: Super Contributor
timestamp: August 10, 2017, 09:05:25 pm
content: Quote from: Geoff_S on August 10, 2017, 08:54:09 pmI read the post as having the clock rate be about 4% too fast, not >100% too fast.

author: sleemanj
author_rank: Super Contributor
timestamp: August 10, 2017, 09:55:25 pm
content: Yes as far as I know it is up to you to shove the value into osccal at runtime as it were, the factory cal is is not (officially?) modifiable.

author: Geoff_S
author_rank: Regular Contributor
timestamp: August 10, 2017, 10:51:51 pm
content: Quote from: sokoloff on August 10, 2017, 09:05:25 pmAh yes, sorry. I read "approx. 10kbaud - too fast!" as "approx. 10kbaud too fast!"

author: HwAoRrDk
author_rank: Super Contributor
timestamp: August 10, 2017, 11:51:17 pm
content: Yes, too fastat10kbaud, not too fastby10kbaud.Quote from: sleemanj on August 10, 2017, 09:55:25 pmOh, read-only, huh? I guess that figures, seeing as it's part of the device's signature info, which you wouldn't otherwise want to be modifiable.So you only get to set/modify OSCCAL in code? Not exactly convenient for deploying the same code to multiple devices... but then again I suppose you could put your OSCCAL value in EEPROM. I could just doOSCCAL0 = eeprom_read_byte(...)as the first line ofmain().Actually, having said that, perhaps that is what the whole flash/EEPROM option in the oscillator calibration feature of Atmel Studio's programming tool is about. Perhaps you're supposed to press 'Read' to grab the factory cal. value off the chip, adjust the value as necessary, then enter the address where you want the value written to either EEPROM or program flash and press 'Write', overwriting whatever default value is currently there. That's the only way I can see that tool making sense. I'll have to see if I can dig up some docs on it.

author: senso
author_rank: Frequent Contributor
timestamp: August 11, 2017, 02:44:26 pm
content: You can program OSCCAL via ISP, Atmel Studio with a Dragon connected as a tab called Osc Cal in the Device Programming window..

author: HwAoRrDk
author_rank: Super Contributor
timestamp: August 11, 2017, 07:32:59 pm
content: You mean this window?That's what I was talking about above.I did manage to find a copy of the Atmel Studio user's guide, and it had the following to say about the oscillator calibration programming tool:QuoteI tried it out by doing the following: I read the device's factory cal value, then entered an address of0x00, chose EEPROM and wrote it to the chip. Then I read and saved the entirety of the EEPROM to a file and opened it in Notepad. As expected, the first byte (i.e. address zero) contained the value.So, it works as I predicted - but with one exception. You cannot modify the value before writing back to flash/EEPROM. So it seems the tool is only for copying the factory cal. value as-is.Anyway, given that, I am thinking of doing this: having two bytes in EEPROM, the first for keeping the factory cal. value, and the second for the necessary adjustment value. Then all I have to do is program the EEPROM with my base config (I have a couples of lookup tables to go there as well), then use the method above to copy the oscillator cal. value over the top of the first byte. The code will then read both bytes and set OSCCAL0 with the appropriate value at startup.

author: cv007
author_rank: Frequent Contributor
timestamp: August 12, 2017, 12:47:41 am
content: I have not touched an Atmel part in many years, so consider that, but-QuoteI suspect you are not reading the factory cal value, but are running a calibration via isp and ending up with a value that is better than the factory cal value (you could verify by reading the cal value from the signature bytes- if they are different, then that is what is happening).http://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en591393Quoteno need to store the factory cal byte anywhere, its already loaded to OSCCAL0 at reset- just read OSCCAL0 if you want it (I'm not sure why you want it).I suspect it goes something like this-OSCCAL0 loaded at reset from signature cal byteuser not happy as conditions don't match factory (voltage/temp)user runs isp calibration at desired voltage/temp, gets a better cal valuesaves better value somewhere (flash or eeprom)user app loads better value (from flash or eeprom) into OSCCAL0 at startupuser is happy, for now

author: HwAoRrDk
author_rank: Super Contributor
timestamp: August 12, 2017, 01:47:25 am
content: Quote from: cv007 on August 12, 2017, 12:47:41 amNo, I don't think that is what happens. As you can see from the excerpt from the Atmel Studio user guide above, it specifically says:QuoteAnd it does not mention anything about actually making a calibration. (And I just noticed that sentence in the docs could use some fixing - there is no 'Advanced' tab.)

author: JimRemington
author_rank: Regular Contributor
timestamp: August 12, 2017, 02:58:10 am
content: QuoteThis has worked well for me, and calibration can be done programmatically (on the chip in question) using an accurate external clock source as input to Timer1 in capture mode.

author: cv007
author_rank: Frequent Contributor
timestamp: August 12, 2017, 10:50:34 am
content: QuoteThen the only value to that oscillator settings tab is for avr's that do not load the cal val from the signature byte automatically, or for those that have multiple cal values (1MHz,8MHz, etc.) and you want to use the cal value other than the one that is loaded automatically (which is why they would have the drop down frequency selector).If that is the case, then you are on your own. Come up with a cal value you want, store it in flash/eeprom, read it at startup, store it in OSCCAL0.If it were me, I would spend the 50cents to hang a crystal on it and forget about all the trouble of dealing with frequency calibration. Or at least come up with a way to get it close without having to deal with each chip individually (you know the original OSCCAL0 value since its loaded for you, you probably can get a good offset value for your voltage, so simply OSCCAL0 += my_offset may get close).

author: David Hess
author_rank: Super Contributor
timestamp: August 12, 2017, 03:45:17 pm
content: Quote from: JimRemington on August 12, 2017, 02:58:10 amCould the timing be extracted from the UART receiver listening to RS-232 traffic?

author: 2N3055
author_rank: Super Contributor
timestamp: August 12, 2017, 04:13:05 pm
content: Use crystal..Internal oscillator has 30% error swing over full temp range.... It will never be reliable without crystal.