diff options
author | Karl Shea <karlshea@gmail.com> | 2021-11-29 09:07:36 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-29 15:07:36 +0000 |
commit | 84b8cdc1a43245d24b232bc8e28cca7f1183d676 (patch) | |
tree | ff497f2cc3a2390e70d87e1ad3252050682a26d0 /quantum | |
parent | 23d3ebd78a5ce823f36abb19b73df900a84d1912 (diff) | |
download | qmk_firmware-84b8cdc1a43245d24b232bc8e28cca7f1183d676.tar.gz qmk_firmware-84b8cdc1a43245d24b232bc8e28cca7f1183d676.zip |
Fix bit loss in cie_lightness() when doing division to resolve #15331 (#15344)
* Fix bit loss in cie_lightness() when doing division.
* Use the right types
* Format
Co-authored-by: zvecr <git@zvecr.com>
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/backlight/backlight_avr.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c index 67b551dc3..9c972ae02 100644 --- a/quantum/backlight/backlight_avr.c +++ b/quantum/backlight/backlight_avr.c | |||
@@ -232,19 +232,19 @@ ISR(TIMERx_OVF_vect) { | |||
232 | 232 | ||
233 | // See http://jared.geek.nz/2013/feb/linear-led-pwm | 233 | // See http://jared.geek.nz/2013/feb/linear-led-pwm |
234 | static uint16_t cie_lightness(uint16_t v) { | 234 | static uint16_t cie_lightness(uint16_t v) { |
235 | if (v <= ICRx / 12) // If the value is less than or equal to ~8% of max | 235 | if (v <= (uint32_t)ICRx / 12) // If the value is less than or equal to ~8% of max |
236 | { | 236 | { |
237 | return v / 9; // Same as dividing by 900% | 237 | return v / 9; // Same as dividing by 900% |
238 | } else { | 238 | } else { |
239 | // In the next two lines values are bit-shifted. This is to avoid loosing decimals in integer math. | 239 | // In the next two lines values are bit-shifted. This is to avoid loosing decimals in integer math. |
240 | uint32_t y = (((uint32_t)v + ICRx / 6) << 5) / (ICRx / 6 + ICRx); // If above 8%, add ~16% of max, and normalize with (max + ~16% max) | 240 | uint32_t y = (((uint32_t)v + (uint32_t)ICRx / 6) << 5) / ((uint32_t)ICRx / 6 + ICRx); // If above 8%, add ~16% of max, and normalize with (max + ~16% max) |
241 | uint32_t out = (y * y * y * ICRx) >> 15; // Cube it and undo the bit-shifting. (which is now three times as much due to the cubing) | 241 | uint32_t out = (y * y * y * ICRx) >> 15; // Cube it and undo the bit-shifting. (which is now three times as much due to the cubing) |
242 | 242 | ||
243 | if (out > ICRx) // Avoid overflows | 243 | if (out > ICRx) // Avoid overflows |
244 | { | 244 | { |
245 | out = ICRx; | 245 | out = ICRx; |
246 | } | 246 | } |
247 | return out; | 247 | return (uint16_t)out; |
248 | } | 248 | } |
249 | } | 249 | } |
250 | 250 | ||