On my setup with IDE 1.8.10 (not sure how to tell the toolchain version?), the failure can be observed with default optimization of size and O2 and O3. O 0 and O1 work fine.
For reference, here is how to override the toolchain default (replace -O1 to -Os, -O3, etc):
void loop() attribute((optimize("-O1")));
The following 2 lines reproduce the failure on my setup.
void loop() {
analogWrite(RED, 0x3E);
analogWrite(RED, 0x7E); // Works if this line is changed to ananlogWrite(RED, 0xFF);
}
Note: If I add a print the int loop, I can confirm the loop code is being hit.
After running an objdump on the working and failure cases, I am unable to understand the assembly enough to pinpoint where the failure is happening, Perhaps someone can spot what is going on. Note that in the examples below, I have left default optimization of size on.
See below for failure and success assembly. I have also attached the entire assembly dump.
Can anyone suggest how to properly raise a defect against this issue so it is properly tracked and fixed?
Failure assembly fragment (I don't see any smoking gun here):
for (;;) {
loop();
if (serialEventRun) serialEventRun();
65a: c0 e0 ldi r28, 0x00 ; 0
65c: d0 e0 ldi r29, 0x00 ; 0
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
65e: 89 e0 ldi r24, 0x09 ; 9
660: d7 dd rcall .-1106 ; 0x210 <pinMode.constprop.0>
662: 6e e3 ldi r22, 0x3E ; 62
664: 70 e0 ldi r23, 0x00 ; 0
666: 89 e0 ldi r24, 0x09 ; 9
668: 7d de rcall .-774 ; 0x364 <analogWrite.part.0>
66a: 89 e0 ldi r24, 0x09 ; 9
66c: d1 dd rcall .-1118 ; 0x210 <pinMode.constprop.0>
66e: 6e ef ldi r22, 0xFE ; 254
670: 70 e0 ldi r23, 0x00 ; 0
672: 89 e0 ldi r24, 0x09 ; 9
674: 77 de rcall .-786 ; 0x364 <analogWrite.part.0>
676: 20 97 sbiw r28, 0x00 ; 0
678: 91 f3 breq .-28 ; 0x65e <main+0xe4>
67a: 0e 94 00 00 call 0 ; 0x0 <__vectors>
67e: ef cf rjmp .-34 ; 0x65e <main+0xe4>
Success case fragment:
{
digitalWrite(pin, HIGH);
}
else
{
switch(digitalPinToTimer(pin))
4d8: 8d ee ldi r24, 0xED ; 237
4da: e8 2e mov r14, r24
4dc: 80 e0 ldi r24, 0x00 ; 0
4de: f8 2e mov r15, r24
#if defined(TCCR5A) && defined(COM5C1)
case TIMER5C:
// connect pwm to pin on timer 5, channel C
sbi(TCCR5A, COM5C1);
OCR5C = val; // set pwm duty
4e0: ce e3 ldi r28, 0x3E ; 62
4e2: d0 e0 ldi r29, 0x00 ; 0
#if defined(TCCR2A) && defined(COM2B1)
case TIMER2B:
// connect pwm to pin on timer 2, channel B
sbi(TCCR2A, COM2B1);
OCR2B = val; // set pwm duty
4e4: 1e e3 ldi r17, 0x3E ; 62
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
4e6: 90 e0 ldi r25, 0x00 ; 0
4e8: c9 2e mov r12, r25
4ea: 90 e0 ldi r25, 0x00 ; 0
4ec: d9 2e mov r13, r25
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
4ee: 89 e0 ldi r24, 0x09 ; 9
4f0: 8f de rcall .-738 ; 0x210 <pinMode.constprop.0>
{
digitalWrite(pin, HIGH);
}
else
{
switch(digitalPinToTimer(pin))
4f2: f7 01 movw r30, r14
4f4: 84 91 lpm r24, Z
4f6: ef ef ldi r30, 0xFF ; 255
4f8: e8 0f add r30, r24
4fa: e2 31 cpi r30, 0x12 ; 18
4fc: 08 f0 brcs .+2 ; 0x500 <__LOCK_REGION_LENGTH__+0x100>
4fe: ba c0 rjmp .+372 ; 0x674 <__LOCK_REGION_LENGTH__+0x274>
500: f0 e0 ldi r31, 0x00 ; 0
502: 88 27 eor r24, r24
504: ea 57 subi r30, 0x7A ; 122
506: fd 4f sbci r31, 0xFD ; 253
508: 8f 4f sbci r24, 0xFF ; 255
50a: b8 c0 rjmp .+368 ; 0x67c <__tablejump