128 lines
3.0 KiB
C
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;
|
|
}
|