Regarding calibration I came up with the following idea:
(I will use SDCC from now on for any future development)
If somebody wants to insert calibration in a program we can do this by using a sequence of NOP instructions.
So if somebody compiles the program and uses a programmer which does not support calibration the NOP sequence will not do any harm.
Now the trick. Instead of using plain simple NOPs I plan to use a sequence of "AND A, ..."
Since it is absolutely impossible that someone wants to AND A a times in a row with different values we can use the immediate 8 bit value to encode information and have a strong marker:
and a, #'I'
and a, #'H'
and a, #'R'
and a, #'C'
and a, #(16000000)
and a, #(16000000)>>8
and a, #(16000000)>>16
and a, #(16000000)>>24
Like this we can encode a marker ("IHRC" for calibration of internal high speed RC / "ILRC" of the internal low speed RC) and the desired tuning frequency.
If you compile and flash the code with another programmer without doing calibration it will just do 8 ANDs and most likely result in A=0 since frequency>>24 is for sure not desired ;-)
Easy-PDK-Writer now can scan the binary for the magic ANDs with 'I' 'H' 'R' 'C' / 'I' 'L' 'R' 'C' + frequency value, dynamically insert the calibration code, write the IC, do the calibration, write the calibration result to IC and change the calibration code to NOPs.
TO make it more convenient I wrote 2 macros for SDCC:
#define EASY_PDK_CALIBRATE_IHRC(frequency) \
__asm__( \
"and a, #'I' \n"\
"and a, #'H' \n"\
"and a, #'R' \n"\
"and a, #'C' \n"\
"and a, #("#frequency") \n"\
"and a, #("#frequency">>8) \n"\
"and a, #("#frequency">>16) \n"\
"and a, #("#frequency">>24) \n"\
)
#define EASY_PDK_CALIBRATE_ILRC(frequency) \
__asm__( \
"and a, #'I' \n"\
"and a, #'L' \n"\
"and a, #'R' \n"\
"and a, #'C' \n"\
"and a, #("#frequency") \n"\
"and a, #("#frequency">>8) \n"\
"and a, #("#frequency">>16) \n"\
"and a, #("#frequency">>24) \n"\
)
So if you want to insert calibration to your program you only have to add one line to _sdcc_external_startup after setting clkmd:
unsigned char _sdcc_external_startup(void)
{
clkmd = 0x34; // Use IHRC / 2 = 8 Mhz for system clock, disable ILRC, disable watchdog
EASY_PDK_CALIBRATE_IHRC(8000000); // calibrate IHRC to 8 MHz system clock
return 0;
}
What do you think?
JS