I was thinking of creating calibration code for Internal Highspeed RC (IHRC) and came up with the following minimal code:
_STARTUP:
GOTO _CALIBRATION ;jump to calibration code, will be overwritten with NOP after calibration
MOV A,0xFF ;immediate value 0xFF with all bits 1, will be changed to MOV A,0x12 (0x12 = determined calibration value) after calibration was done
MOV IHRCR, A ;set the calibration value
;set SP, init .BSS, init .DATA, ...
;user code here
;----------------------------------------------------------------
.RAMADR 0
BYTE TMP
.ROMADR 0x7D0
_CALIBRATION:
CLEAR TMP ;set TMP to 0
_CAL_NEXT_STEP:
MOV A,0x10 ;PA.5 as output, rest as input => this pin should exist on all devices, same as RESET/ICVPP pin
MOV PAC,A
_CAL_WAIT_HOST:
T1SN PA.6 ;read bit from PA.6 (measurement start?) => this pin should exist on all devices, same as ICPDA pin
GOTO _CAL_WAIT_HOST
_CAL_TOGGLE_LOOP:
XOR PA,A ;invert output of PA.5
T0SN PA.6 ;read bit from PA.6 (measurment done?)
GOTO _CAL_TOGGLE_LOOP
INC TMP ;increment TMP value (will run from 0 - 255, increment by 1 with each measurement done single)
MOV A,TMP ;read the current TMP value
MOV IHRCR, A ;write current TMP value to IHRCR tuning register
GOTO _CAL_NEXT_STEP ;jump to next calibration step
;------------------------------------------------------------------------
;assembly output (14 bit) of the calibration (12 instructions)
0x07d0: 0x1300 CLEAR [0x00]
0x07d1: 0x2f10 MOV A, 0x10
0x07d2: 0x0191 MOV IO(0x11), A ;PAC
0x07d3: 0x1b90 T1SN IO(0x10).6 ;PA.6
0x07d4: 0x37d3 GOTO 0x7D3
0x07d5: 0x00d0 XOR IO(0x10), A ;PA
0x07d6: 0x1990 T0SN IO(0x10).6 ;PA.6
0x07d7: 0x37d5 GOTO 0x7D5
0x07d8: 0x1200 INCM [0x00]
0x07d9: 0x0f80 MOV A, [0x00]
0x07da: 0x018b MOV IO(0x0B), A ;IHRCR
0x07db: 0x37d1 GOTO 0x7D1
STARTUP CODE:
1st instrucrtion is a GOTO to the calibration code, this GOTO will be changed to a NOP after calibration was done
-> this is faster and more compact than PADAUK code since no stack setup is required for the CALL and CALL+RET wastes more cycles than overwrite GOTO with NOP (actually the calibration never need to return since we can reset/unpower the IC to leave this mode)
2nd instruction is a MOV A,0xFF which can be overwritten to anything like MOV A,0x.. later (this will receive the calibration value)
-> again faster
3rd instructions sets the IHRCR tuning register value
...
CALIBRATION CODE:
PA.5 is used as output from IC which toggles on/off in a tight loop => output max is up to 9 MHz which can be captured and counted in hardware on host MCU easily (e.g. TIM on STM32); measurement of how many toggle in specific time period
PA.6 is used as input to IC to signal measurement start and measurement done, after each measurement done the value of IHRCR is incremented and the next measurement can start
-> this is slower than PADAUK since we can not go up/down (+1/-1) we have to cycle over all 256 values of the byte instead, but it is a lot more compact, and calibration does not need to be so fast...
So now asking you for creative ideas to make it even more compact ( < 3 + 12 instructions )
JS