Closed Ho-Ro closed 2 years ago
Solution:
void timer2_isr( void ) __interrupt TF2_ISR {
/* Toggle the probe calibration pin. */
TOGGLE_CALIBRATION_PIN();
#ifdef LED_RED_TOGGLE
// Avoid nasty sdcc 4.0 REGRESSION:
// Do not use "if ( ledcounter && --ledcounter == 0 )"
// Write separate statements!
// Otherwise the ISR uses registers for reload -> additional push/pop ...
// ... more cycles, fails for 100 kHz
if ( ledcounter ) {
--ledcounter;
if ( ledcounter == 0 ) { // led timed out?
ledcounter = ledinit; // reload
LED_RED_TOGGLE();
}
}
#endif
TF2 = 0;
}
EDIT: SDCC 4.0 translates this into a faster asm code without registers:
1198 ;------------------------------------------------------------
1199 ;Allocation info for local variables in function 'timer2_isr'
1200 ;------------------------------------------------------------
1201 ; scope6022.inc:76: void timer2_isr( void ) __interrupt TF2_ISR {
1202 ; -----------------------------------------
1203 ; function timer2_isr
1204 ; -----------------------------------------
1205 _timer2_isr:
1206 push acc
1207 push psw
1208 ; scope6022.inc:78: TOGGLE_CALIBRATION_PIN();
1209 cpl _PA7
1210 ; scope6022.inc:85: if ( ledcounter ) {
1211 mov a,_ledcounter
1212 orl a,(_ledcounter + 1)
1213 jz 00110$
1214 ; scope6022.inc:86: --ledcounter;
1215 dec _ledcounter
1216 mov a,#0xff
1217 cjne a,_ledcounter,00122$
1218 dec (_ledcounter + 1)
1219 00122$:
1220 ; scope6022.inc:87: if ( ledcounter == 0 ) { // led timed out?
1221 mov a,_ledcounter
1222 orl a,(_ledcounter + 1)
1223 jnz 00110$
1224 ; scope6022.inc:88: ledcounter = ledinit; // reload
1225 mov _ledcounter,_ledinit
1226 mov (_ledcounter + 1),(_ledinit + 1)
1227 ; scope6022.inc:89: LED_RED_TOGGLE();
1228 cpl _PC0
1229 ; assignBit
1230 setb _PC1
1231 00110$:
1232 ; scope6022.inc:93: TF2 = 0;
1233 ; assignBit
1234 clr _TF2
1235 ; scope6022.inc:94: }
1236 pop psw
1237 pop acc
1238 reti
1239 ; eliminated unneeded mov psw,# (no regs used in bank)
1240 ; eliminated unneeded push/pop dpl
1241 ; eliminated unneeded push/pop dph
1242 ; eliminated unneeded push/pop b
Well done, it's fixed now. Thanks for the great work! .
Mentioned there by @iss000: The problem is missing pulses when calibration freq is set to 100kHz (every lower freq is OK).
The calibration pulse is created via timer2_isr() (source):
The timer is initialized in set_calibration_pulse() (source):
Debian buster version:
Debian bullseye version
As an intermediate containment action I reverted to the buster version of SDCC and set it on hold, see 81f6913: