133 lines
2.6 KiB
C
133 lines
2.6 KiB
C
#include "temp.h"
|
|
#include "driver/gpio.h"
|
|
#include "esp_rom_sys.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include <math.h>
|
|
|
|
#define OW_PIN GPIO_NUM_35
|
|
|
|
static float cached_temp = 25.0f;
|
|
static portMUX_TYPE ow_mux = portMUX_INITIALIZER_UNLOCKED;
|
|
|
|
static void ow_low(void)
|
|
{
|
|
gpio_set_level(OW_PIN, 0);
|
|
gpio_set_direction(OW_PIN, GPIO_MODE_OUTPUT);
|
|
}
|
|
|
|
static void ow_release(void)
|
|
{
|
|
gpio_set_direction(OW_PIN, GPIO_MODE_INPUT);
|
|
}
|
|
|
|
static int ow_reset(void)
|
|
{
|
|
ow_low();
|
|
esp_rom_delay_us(480);
|
|
|
|
taskENTER_CRITICAL(&ow_mux);
|
|
ow_release();
|
|
esp_rom_delay_us(70);
|
|
int presence = !gpio_get_level(OW_PIN);
|
|
taskEXIT_CRITICAL(&ow_mux);
|
|
|
|
esp_rom_delay_us(410);
|
|
return presence;
|
|
}
|
|
|
|
static void ow_write_bit(int bit)
|
|
{
|
|
taskENTER_CRITICAL(&ow_mux);
|
|
ow_low();
|
|
if (bit) {
|
|
esp_rom_delay_us(6);
|
|
ow_release();
|
|
taskEXIT_CRITICAL(&ow_mux);
|
|
esp_rom_delay_us(54);
|
|
} else {
|
|
esp_rom_delay_us(60);
|
|
ow_release();
|
|
taskEXIT_CRITICAL(&ow_mux);
|
|
esp_rom_delay_us(1);
|
|
}
|
|
}
|
|
|
|
static int ow_read_bit(void)
|
|
{
|
|
taskENTER_CRITICAL(&ow_mux);
|
|
ow_low();
|
|
esp_rom_delay_us(2);
|
|
ow_release();
|
|
esp_rom_delay_us(12);
|
|
int bit = gpio_get_level(OW_PIN);
|
|
taskEXIT_CRITICAL(&ow_mux);
|
|
esp_rom_delay_us(46);
|
|
return bit;
|
|
}
|
|
|
|
static void ow_write_byte(uint8_t byte)
|
|
{
|
|
for (int i = 0; i < 8; i++) {
|
|
ow_write_bit(byte & 1);
|
|
byte >>= 1;
|
|
}
|
|
}
|
|
|
|
static uint8_t ow_read_byte(void)
|
|
{
|
|
uint8_t byte = 0;
|
|
for (int i = 0; i < 8; i++)
|
|
if (ow_read_bit())
|
|
byte |= (1 << i);
|
|
return byte;
|
|
}
|
|
|
|
static float ds18b20_read(void)
|
|
{
|
|
if (!ow_reset()) return NAN;
|
|
ow_write_byte(0xCC); /* Skip ROM */
|
|
ow_write_byte(0x44); /* Convert T */
|
|
vTaskDelay(pdMS_TO_TICKS(750));
|
|
|
|
if (!ow_reset()) return NAN;
|
|
ow_write_byte(0xCC);
|
|
ow_write_byte(0xBE); /* Read Scratchpad */
|
|
|
|
uint8_t lsb = ow_read_byte();
|
|
uint8_t msb = ow_read_byte();
|
|
|
|
int16_t raw = (msb << 8) | lsb;
|
|
return raw / 16.0f;
|
|
}
|
|
|
|
static void temp_task(void *arg)
|
|
{
|
|
(void)arg;
|
|
for (;;) {
|
|
float t = ds18b20_read();
|
|
if (!isnan(t))
|
|
cached_temp = t;
|
|
vTaskDelay(pdMS_TO_TICKS(500));
|
|
}
|
|
}
|
|
|
|
void temp_init(void)
|
|
{
|
|
gpio_config_t io = {
|
|
.pin_bit_mask = (1ULL << OW_PIN),
|
|
.mode = GPIO_MODE_INPUT,
|
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
.intr_type = GPIO_INTR_DISABLE,
|
|
};
|
|
gpio_config(&io);
|
|
|
|
xTaskCreate(temp_task, "temp", 2048, NULL, 3, NULL);
|
|
}
|
|
|
|
float temp_get(void)
|
|
{
|
|
return cached_temp;
|
|
}
|