Files
gronod f87ab0c65f
ci / test (push) Successful in 1m9s
ci / firmware (wroom, sdkconfig.wroom, esp32) (push) Successful in 4m9s
ci / firmware (jc4827w543, sdkconfig.s3, esp32s3) (push) Successful in 4m10s
Fix temp_task starvation bug on non-WROOM
2026-09-16 21:21:12 +01:00

128 lines
3.0 KiB
C

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "onewire_bus.h"
#include "board.h"
#include "hal_temp.h"
#define TEMP_OFFSET 0.4f
#define CMD_SKIP_ROM 0xCC
#define CMD_CONVERT_T 0x44
#define CMD_READ_SCRATCH 0xBE
static const char *TAG = "temp";
static onewire_bus_handle_t s_bus;
static bool s_inited;
static float s_last_c;
static bool s_last_ok;
static bool scratch_valid(const uint8_t *sp)
{
/* DS18B20 CRC8 over first 8 bytes, poly 0x8C reflected. */
uint8_t crc = 0;
for (int i = 0; i < 8; i++) {
uint8_t in = sp[i];
for (int b = 0; b < 8; b++) {
uint8_t mix = (crc ^ in) & 0x01;
crc >>= 1;
if (mix) {
crc ^= 0x8C;
}
in >>= 1;
}
}
return crc == sp[8];
}
void hal_temp_tick(void)
{
if (s_bus == NULL) {
s_last_ok = false;
vTaskDelay(pdMS_TO_TICKS(750));
return;
}
if (onewire_bus_reset(s_bus) != ESP_OK) {
s_last_ok = false;
vTaskDelay(pdMS_TO_TICKS(750));
return;
}
uint8_t conv[2] = {CMD_SKIP_ROM, CMD_CONVERT_T};
if (onewire_bus_write_bytes(s_bus, conv, 2) != ESP_OK) {
s_last_ok = false;
vTaskDelay(pdMS_TO_TICKS(750));
return;
}
vTaskDelay(pdMS_TO_TICKS(750));
if (onewire_bus_reset(s_bus) != ESP_OK) {
s_last_ok = false;
return;
}
uint8_t rd[2] = {CMD_SKIP_ROM, CMD_READ_SCRATCH};
if (onewire_bus_write_bytes(s_bus, rd, 2) != ESP_OK) {
s_last_ok = false;
return;
}
uint8_t sp[9];
memset(sp, 0, sizeof(sp));
if (onewire_bus_read_bytes(s_bus, sp, sizeof(sp)) != ESP_OK) {
s_last_ok = false;
return;
}
if (!scratch_valid(sp)) {
s_last_ok = false;
return;
}
int16_t raw = (int16_t)((uint16_t)sp[0] | ((uint16_t)sp[1] << 8));
float t = ((float)raw) / 16.0f + TEMP_OFFSET;
s_last_c = t;
s_last_ok = true;
}
void hal_temp_init(void)
{
if (s_inited) {
return;
}
gpio_num_t pin = board_pin_temp();
if (pin == GPIO_NUM_NC) {
ESP_LOGW(TAG, "no temp pin on this board");
s_inited = true;
return;
}
onewire_bus_config_t bus_config = {
.bus_gpio_num = pin,
.flags = {
.en_pull_up = true,
},
};
onewire_bus_rmt_config_t rmt_config = {
.max_rx_bytes = 10,
};
if (onewire_new_bus_rmt(&bus_config, &rmt_config, &s_bus) != ESP_OK) {
s_bus = NULL;
ESP_LOGE(TAG, "onewire_bus install failed pin=%d", pin);
}
s_last_ok = false;
s_last_c = 0.0f;
s_inited = true;
ESP_LOGI(TAG, "init onewire_bus pin=%d offset=%.1f", pin, (double)TEMP_OFFSET);
}
esp_err_t hal_temp_read_c(float *out)
{
if (!s_last_ok) {
return ESP_FAIL;
}
if (out != NULL) {
*out = s_last_c;
}
return ESP_OK;
}