Dear all,
I am stumbling into an issue that I can't manage to resolve myself. It involves an ISR procedure that works only under certain circumstances.
Background of the matter is a 64x64 pixel display showing an illuminated street number of the house. This display is measuring the surrounding light to determine its brightness (off during daytime, bright at dawn and dusk, dimmed at night). The measurement is done by charging 47nF across 330R to 3.3V and then letting the cap discharge across an LPT80A and measuring the time until 0.95V are crossed.
The crossing is detected by using the CMP0 analog comparator of the T3.2. An interrupt routine is set up to be called after the crossing occurred. It saves away the bus clock tick that the comparator filled in at the time of crossing. This is the code of the ISR:
However, with this code cmp_scr is never set. But if I change the code to the following:
This code works absolutely fine.
I'm totally puzzled what is going on here. I had a quick glance at the generated assembler, but in both cases the assembler code looks ok. One difference that I spot is that in the 3-line version of the ISR no push and pop of registers is necessary, but that's basically where my capabilities end for now.
I attach an example cmp0issue.ino file that reproduces the issue. I trimmed it down as much as I could. I'm using Teensyduino 1.53 on Arduino 1.8.13, which gives me gcc 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]. To reproduce you need a 330R, a 47nF and a 10k between P12, P11 and GND as indicated in the file header. My rig shows ~28500 busticks when it works, and 48000000 (F_BUS) when it doesn't and cmp_scr is not being set..
Any help appreciated, not only a solution but also how to proceed to home in on the issue.
Kind regards,
Sebastian
I am stumbling into an issue that I can't manage to resolve myself. It involves an ISR procedure that works only under certain circumstances.
Background of the matter is a 64x64 pixel display showing an illuminated street number of the house. This display is measuring the surrounding light to determine its brightness (off during daytime, bright at dawn and dusk, dimmed at night). The measurement is done by charging 47nF across 330R to 3.3V and then letting the cap discharge across an LPT80A and measuring the time until 0.95V are crossed.
The crossing is detected by using the CMP0 analog comparator of the T3.2. An interrupt routine is set up to be called after the crossing occurred. It saves away the bus clock tick that the comparator filled in at the time of crossing. This is the code of the ISR:
Code:
volatile uint8_t cmp_scr;
volatile uint32_t cmp_tick;
void cmp_isr (void) {
cmp_tick = PIT_CVAL3;
cmp_scr = CMP0_SCR; // Guaranteed not 0 (either IEF or IER are set, otherwise we would't be called)
CMP0_SCR = 0b00000110; // rsv, !DMAEN, rsv, !IEF, !IER, CFR cleared, CFF cleared, rsv
}
However, with this code cmp_scr is never set. But if I change the code to the following:
Code:
volatile uint8_t cmp_scr;
volatile uint32_t cmp_tick;
uint8_t avoidbug = 0;
void cmp_isr (void) {
avoidbug++; // Something needs to happen here, otherwise cmp_scr is never set. Very strange!
cmp_tick = PIT_CVAL3;
cmp_scr = CMP0_SCR; // Guaranteed not 0 (either IEF or IER are set, otherwise we would't be called)
CMP0_SCR = 0b00000110; // rsv, !DMAEN, rsv, !IEF, !IER, CFR cleared, CFF cleared, rsv
}
This code works absolutely fine.
I'm totally puzzled what is going on here. I had a quick glance at the generated assembler, but in both cases the assembler code looks ok. One difference that I spot is that in the 3-line version of the ISR no push and pop of registers is necessary, but that's basically where my capabilities end for now.
I attach an example cmp0issue.ino file that reproduces the issue. I trimmed it down as much as I could. I'm using Teensyduino 1.53 on Arduino 1.8.13, which gives me gcc 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]. To reproduce you need a 330R, a 47nF and a 10k between P12, P11 and GND as indicated in the file header. My rig shows ~28500 busticks when it works, and 48000000 (F_BUS) when it doesn't and cmp_scr is not being set..
Any help appreciated, not only a solution but also how to proceed to home in on the issue.
Kind regards,
Sebastian