arduino / arduino/ArduinoCore-avr

analog_write() in "wiring_analog.c": wrong management of input val

Open
#418 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
1.5k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

Hello, the analogWrite() function takes the pin number which is uint8_t type and the target value of pwm duty cycle which is int type. Using 16 bit type for the target value is correct since some of the timers (for example TIMER-1 on 328p) have 16 bits resolution. Anyway, at the beginning of the function there is a check if the value is 255.

...
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
....

In that case, the code sets the pin output steady high. This seems to be incorrect for pins supporting 16 bit timers. Nevertheless, if the input value is for example 258, the check is skept and the value is assigned to the timer register (es. ORC1A/B).
This is apparently inconsistent, maybe the code should check ">=255" instead of "==255"? Or the check should be against 65535 for pins supporting 16 bit resolution? Finally, why "val" parameter is int type instead of uint16_t?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in wiring_analog.c at analogWrite() and trace the timer-specific branches and register widths for the ATmega328P. Compare behavior for values 255, 258, and the maximum supported duty values, then determine the intended boundary and parameter type. Done means the behavior is consistent across 8-bit and 16-bit timer pins and is covered by an appropriate regression check.

Written by the indexing model from the issue text.

Assessment

Tech stack
arduino, c
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.