Can anyone tell me the format and meaning of the OSCCAL numbers?

Discussion in 'Embedded Systems and Microcontrollers' started by rudyauction8, Sep 9, 2013.

  1. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    I lost my osccal #, it's causing problems with serial communication and program verification. I am going to write a simple program that will increment the OSCCAL value and send the value to my serial LCD screen, when it works I have the right #. But I don't know what the #'s mean and which ones to access. I'm using picbasic pro. The chip is a 16f630. Thanks in advance for any advice. And I have no fancy tools and my programmer can't recover the value, I'm broke so I won't be buying these things for a $2 chip. Thanks.
  2. JohnInTX


    Jun 26, 2012
    You probably know some/all of this but here are the basics and a way to reprogram the OSCCAL value.

    The factory-calibrated value for OSCCAL is a retlw XX located at 3FFh in program ROM and gets erased with the rest of the flash. Its the responsibility of the chip programmer to read 3FFh, erase the flash then program with the new code and add the retlw XX back. of the datasheet shows CAL5-CAL0 plus 2 unused bits. The default value is 100000xx, the midpoint of the calibration range. On reset, the program should call 3FFh, and the retlw returns the factory setting for CAL5-CAL0 which the code then moves to OSCCAL. Exactly how BASIC does it I don't know but it should provide a way. It may do it automatically in the startup code.

    When uCHIP tests the chip, they write the appropriate data for the retlw to return. This value is determined by test and how the oscillator changes per CAL5-0 value is not specified (it may not be constant from chip to chip). The programming reference has more info on this but still no specific values. See Bulk Erase Program Memory

    If you have lost the retlw at 3FFh, you can run OSCCAL at different values until you are happy then manually add the retlw like this:

    In MPLAB 8.x import your .HEX file.
    Click View->Program Memory and click the Machine tab. The disassembled code will be shown.
    Scroll down to the end (address 3FFh), double click in the Disassembly column at that line and type RETLW xx (where xx is your OSCCAL value determined above).
    Set the CONFIG bits in Configure->Configuration Bits
    Program your chip with the updated ROM image.
    Use File->Export to save the updated image as .HEX

    You might be able to force the compiler to put the retlw at 3ffh with inline assembly but it might not let you clobber that factory setting. There might be a compiler directive / config setting to set OSCCAL but I don't know.

    Start at 100000xx and increment/decrement by 4 since the 2 LSbits are don't care. Make sure you can increment and decrement so that when you get close you can toggle back and forth to tune it. Don't forget to debounce your switches.

    If you have a good scope, consider programming TIMER1 to free run and interrupt on each overflow. Toggle an output line each time. Adjust OSCCAL until the measured time equals the calculated number of timer tiks at 4MHz (2^16usec with prescaler==1). In assembler, you could also toggle the IO line then do a bunch of NOPs with a goto at the end. 1us per NOP or IO + 2us for the jump at 4MHz.

    Check your programmer settings to see if you can specify to save the oscillator calibration. If not, your problems will continue..

    Consider using a ceramic resonator (cheap, set the config to HS) or XTAL (XT), especially if you are doing serial comms. The internal osc is somewhat temperature sensitive (Fig 13-15 in the datasheet shows up to a -4.25% change on some devices at the low temp extreme. That's enough to foul async. comms. YMMV

    Note that the BG (BandGap cal bits) are in the CONFIG register. That's another thing that has to be read/restored by the chip programmer. You don't get direct access to these in MPLAB. You would have to know what to write then bugger up the .HEX line containing the CONFIG info (set the bits and recalculate the record's checksum).

    Good luck!

    BTW: Searching for 'Regenerating OSCCAL' , 'Loss of OSCCAL' etc brings up various info about this.

    Finally: its bad form to start a new thread when you have one going on the same subject. At the least, link to the other thread to avoid duplication of effort.
    Last edited: Sep 10, 2013
    absf likes this.
  3. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    Thanks for the information. The commands you mentioned won't work because I'm working with a basic compiler, not the assembly language. I don't have a scope, so I managed to set up a program to increment the OSCCAL value and then output it to the LCD, when the LCD showed the proper values and not random text I noted them and picked the one in the middle. I now have a working chip. The main thing I was confused about, but later figured out through trial and error, was the meaning of each of the digits, because 6 bits is not 4 hex digits. I'm going to write down all of the OSCCAL values for all of my chips for future reference. And I actually have a half dozen ceramic 20mhz resonators in the mail, they'll be here Thursday along with a handful of PICs and other random components if all goes well.