Skip to content

Conversation

@SunjunKim
Copy link
Contributor

@SunjunKim SunjunKim commented Aug 14, 2025

Bug

The fmap implementation in crsf_protocol.h is at risk of underflow errors when the x is fed less than in_min.

static uint16_t ICACHE_RAM_ATTR fmap(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max)
{
    return ((x - in_min) * (out_max - out_min) * 2 / (in_max - in_min) + out_min * 2 + 1) / 2;
}

For example, calling fmap(5, 10, 20, 100, 200) will be result in:
(5-10)*(200-100)*2 ...

However, as the variables are defined as unsigned types, 5-10 = -5 will be wrapped into 65535-5 = 65530, which gives an erroneously large value.

With some old PPM handset, the values could be go outside the defined range.

Fix

Straightforward, constrain the x within in_min -- in_max range.

Story

The bug was discovered when testing an old PPM radio with an ELRS TX; the control surfaces are flipped all the way to the other side when the stick was deflected to its minimum position.

Close investigation revealed that the PPM signal from the radio was outside the hard-coded range of (988, 2012) in PPMHandset.cpp, causing the underflow.

PS. ELRS module installation on an old Futaba radio which discovered this defect:
IMG_8497
IMG_8496
IMG_8498

@SunjunKim SunjunKim changed the title Add constrain to fmap function Constraining PPMHandset ppm value within the CRSF limits Aug 14, 2025
@mha1 mha1 merged commit ff41f67 into ExpressLRS:3.x.x-maintenance Aug 17, 2025
51 checks passed
@SunjunKim SunjunKim deleted the limited_pwm branch August 17, 2025 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants