Conversation
There was a problem hiding this comment.
Pull request overview
Fixes the P3T1755 onboard temperature sensor driver for the Shepherd platform, primarily by adjusting I2C addressing and updating temperature conversion logic.
Changes:
- Left-shift the I2C device address during
p3t1755_init()to match the project’s I2C driver expectations. - Introduce a new raw-to-celsius conversion helper and update
p3t1755_read_temperature()to use it. - Apply formatting/cleanup updates across the driver and header.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
general/src/p3t1755.c |
Updates address handling and rewrites temperature read/convert path (plus formatting). |
general/include/p3t1755.h |
Adds a (problematic) declaration for the new conversion helper and reformats defines/types. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
general/src/p3t1755.c
Outdated
| *temp_c = p3t1755_RAW_TO_CELSIUS( | ||
| uint8_to_uint16(high_temp_reg[0], high_temp_reg[1])); | ||
| return status; |
There was a problem hiding this comment.
Temperature conversion logic is now different between p3t1755_read_temperature() (custom helper + bit shifting) and this threshold read, which still uses p3t1755_RAW_TO_CELSIUS(uint8_to_uint16(...)) with no shifting. If the registers are left-justified (common with 0.0625°C parts), threshold reads will disagree with the current temperature read. Recommend decoding T_HIGH using the same raw->°C path as the TEMPERATURE register (and similarly for T_LOW / threshold writes).
general/src/p3t1755.c
Outdated
| *temp_c = | ||
| p3t1755_RAW_TO_CELSIUS(uint8_to_uint16(low_temp_reg[0], low_temp_reg[1])); |
There was a problem hiding this comment.
Same issue as T_HIGH: this uses p3t1755_RAW_TO_CELSIUS(uint8_to_uint16(...)) without applying the nibble shift/sign-extension logic introduced for the TEMPERATURE register. Consider sharing a single decode routine so T_LOW, T_HIGH, and TEMPERATURE all interpret the sensor’s register format consistently.
general/src/p3t1755.c
Outdated
| int p3t1755_read_temperature(p3t1755_t *p3t, float *temp_c) | ||
| { | ||
| uint8_t temp_reg[2]; | ||
| inline float p3t1755_raw_to_celsius(uint16_t raw) { |
There was a problem hiding this comment.
p3t1755_raw_to_celsius() is defined as inline with external linkage in the .c file, while the header declares it static inline (and without a definition). C inline linkage rules can easily produce missing/duplicate symbols depending on compiler flags. Prefer making this helper static/static inline in the .c file (and removing it from the public header), or provide a single non-inline extern declaration in the header with one .c definition.
| inline float p3t1755_raw_to_celsius(uint16_t raw) { | |
| static inline float p3t1755_raw_to_celsius(uint16_t raw) { |
general/src/p3t1755.c
Outdated
| *temp_c = p3t1755_raw_to_celsius( | ||
| uint8_to_uint16(temp_reg[0] >> 4, temp_reg[1] >> 4)); |
There was a problem hiding this comment.
Temperature register bytes are combined incorrectly: uint8_to_uint16(temp_reg[0] >> 4, temp_reg[1] >> 4) drops most of the MSB and will produce a near-zero raw value (and the sign bit check in p3t1755_raw_to_celsius() will never trigger). Reconstruct the 16-bit register value from the unshifted bytes first, then right-shift by 4 (per the sensor’s 0.0625°C format) before converting to °C.
| *temp_c = p3t1755_raw_to_celsius( | |
| uint8_to_uint16(temp_reg[0] >> 4, temp_reg[1] >> 4)); | |
| uint16_t raw = uint8_to_uint16(temp_reg[0], temp_reg[1]); | |
| raw >>= 4; | |
| *temp_c = p3t1755_raw_to_celsius(raw); |
general/src/p3t1755.c
Outdated
| PRINTLN_INFO("raw temp: %d", raw); | ||
| if (raw & 1 << 11) { // Check if sign bit is set |-> t<0 | ||
| return -(raw * p3t1755_TEMP_RESOLUTION); | ||
| } else | ||
| return (raw * p3t1755_TEMP_RESOLUTION); |
There was a problem hiding this comment.
p3t1755_raw_to_celsius() does not correctly handle negative temperatures. Simply negating raw when a sign bit is set is not equivalent to decoding the 12-bit two’s-complement value; you need to sign-extend the 12-bit quantity (after shifting) into an int16_t and then apply the 0.0625°C resolution.
| PRINTLN_INFO("raw temp: %d", raw); | |
| if (raw & 1 << 11) { // Check if sign bit is set |-> t<0 | |
| return -(raw * p3t1755_TEMP_RESOLUTION); | |
| } else | |
| return (raw * p3t1755_TEMP_RESOLUTION); | |
| /* raw contains a 12-bit two's-complement temperature value */ | |
| uint16_t raw12 = raw & 0x0FFF; /* keep only the lower 12 bits */ | |
| int16_t temp_counts; | |
| if (raw12 & 0x0800) { | |
| /* negative value: sign-extend 12-bit to 16-bit */ | |
| temp_counts = (int16_t)(raw12 | 0xF000); | |
| } else { | |
| /* positive value */ | |
| temp_counts = (int16_t)raw12; | |
| } | |
| PRINTLN_INFO("raw temp counts: %d", temp_counts); | |
| return (float)temp_counts * p3t1755_TEMP_RESOLUTION; |
general/src/p3t1755.c
Outdated
| inline float p3t1755_raw_to_celsius(uint16_t raw) { | ||
| PRINTLN_INFO("raw temp: %d", raw); |
There was a problem hiding this comment.
This helper prints every raw temperature conversion (PRINTLN_INFO("raw temp: ...")). That will spam logs in normal operation and can significantly increase UART/RTOS overhead on a periodic sensor read. Consider removing this, or gating it behind a compile-time debug flag / higher log level used only during bring-up.
| inline float p3t1755_raw_to_celsius(uint16_t raw) { | |
| PRINTLN_INFO("raw temp: %d", raw); | |
| inline float p3t1755_raw_to_celsius(uint16_t raw) { | |
| #ifdef P3T1755_DEBUG | |
| PRINTLN_INFO("raw temp: %d", raw); | |
| #endif |
general/include/p3t1755.h
Outdated
| ReadPtr read; | ||
| } p3t1755_t; | ||
|
|
||
| static inline float p3t1755_raw_to_celsius(uint16_t raw); |
There was a problem hiding this comment.
Header declares static inline float p3t1755_raw_to_celsius(uint16_t raw); but does not provide a definition. A static inline function should be defined in the header (so each translation unit can inline it), or it should be declared as a normal extern function and defined once in the .c file. As-is, any use from another .c file will fail to link/compile depending on compiler settings.
| static inline float p3t1755_raw_to_celsius(uint16_t raw); | |
| static inline float p3t1755_raw_to_celsius(uint16_t raw) { | |
| return ((int16_t)raw) * p3t1755_TEMP_RESOLUTION; | |
| } |
Changes
Fixes for the p3t1755 onboard temp sensor for Shepherd