1 #include <twr_ds18b20.h> 2 #include <twr_onewire.h> 5 #include <twr_module_sensor.h> 7 #define _TWR_DS18B20_SCRATCHPAD_SIZE 9 8 #define _TWR_DS18B20_DELAY_RUN 5000 11 [TWR_DS18B20_RESOLUTION_BITS_9] = 100,
12 [TWR_DS18B20_RESOLUTION_BITS_10] = 190,
13 [TWR_DS18B20_RESOLUTION_BITS_11] = 380,
14 [TWR_DS18B20_RESOLUTION_BITS_12] = 760
17 static void _twr_ds18b20_task_interval(
void *param);
19 static void _twr_ds18b20_task_measure(
void *param);
21 static int _twr_ds18b20_power_semaphore = 0;
25 static twr_ds18b20_sensor_t sensors[1];
40 memset(
self, 0,
sizeof(*
self));
42 self->_onewire = onewire;
44 self->_resolution = resolution;
45 self->_sensor = sensors;
46 self->_sensor_count = sensor_count;
55 self->_event_handler = event_handler;
56 self->_event_param = event_param;
61 self->_update_interval = interval;
77 if (self->_measurement_active)
82 self->_measurement_active =
true;
91 for (
int i = 0; i <
self->_sensor_found; i++)
93 if (self->_sensor[i]._device_address == device_address)
104 if (index >= self->_sensor_found)
109 uint64_t short_address =
self->_sensor[index]._device_address;
110 short_address &= ~(((uint64_t) 0xff) << 56);
113 return short_address;
118 return self->_sensor_found;
123 self->_power_dynamic = on;
130 if (sensor_index == -1)
135 if (!self->_sensor[sensor_index]._temperature_valid)
140 *raw =
self->_sensor[sensor_index]._temperature_raw;
149 if (sensor_index == -1)
154 if (!self->_sensor[sensor_index]._temperature_valid)
159 if ((device_address & 0xFF) == 0x10)
162 *celsius = (float) self->_sensor[sensor_index]._temperature_raw / 2;
166 *celsius = (float) self->_sensor[sensor_index]._temperature_raw / 16;
172 static void _twr_ds18b20_task_interval(
void *param)
183 if (!self->_power_dynamic)
193 if (_twr_ds18b20_power_semaphore == 0)
212 _twr_ds18b20_power_semaphore++;
221 if (!self->_power_dynamic)
231 if (_twr_ds18b20_power_semaphore == 1)
250 _twr_ds18b20_power_semaphore--;
252 self->_power =
false;
257 static bool _twr_ds18b20_is_scratchpad_valid(uint8_t *scratchpad)
259 #ifdef TWR_DS18B20_STRICT_VALIDATION 260 if (scratchpad[5] != 0xff)
265 if (scratchpad[7] != 0x10)
279 static void _twr_ds18b20_task_measure(
void *param)
285 switch (self->_state)
287 case TWR_DS18B20_STATE_ERROR:
289 for (
int i = 0; i <
self->_sensor_found; i++)
291 self->_sensor[i]._temperature_valid =
false;
294 self->_measurement_active =
false;
296 _twr_ds18b20_power_down(
self);
298 if (self->_event_handler != NULL)
303 self->_state = TWR_DS18B20_STATE_PREINITIALIZE;
307 case TWR_DS18B20_STATE_PREINITIALIZE:
309 self->_state = TWR_DS18B20_STATE_ERROR;
311 if (self->_power_dynamic)
315 if (!_twr_ds18b20_power_up(
self))
321 self->_state = TWR_DS18B20_STATE_INITIALIZE;
327 case TWR_DS18B20_STATE_INITIALIZE:
329 self->_state = TWR_DS18B20_STATE_ERROR;
331 uint64_t _device_address = 0;
332 self->_sensor_found = 0;
336 while ((self->_sensor_found < self->_sensor_count) &&
twr_onewire_search_next(self->_onewire, &_device_address))
338 self->_sensor[
self->_sensor_found]._device_address = _device_address;
341 self->_sensor_found++;
344 if (self->_sensor_found == 0)
362 uint8_t buffer[] = {0x4e, 0x75, 0x70,
self->_resolution << 5 | 0x1f};
368 if (self->_measurement_active)
374 if (!_twr_ds18b20_power_down(
self))
380 self->_state = TWR_DS18B20_STATE_READY;
384 case TWR_DS18B20_STATE_READY:
386 self->_state = TWR_DS18B20_STATE_ERROR;
388 if (!_twr_ds18b20_power_up(
self))
393 self->_state = TWR_DS18B20_STATE_MEASURE;
399 case TWR_DS18B20_STATE_MEASURE:
401 self->_state = TWR_DS18B20_STATE_ERROR;
418 self->_state = TWR_DS18B20_STATE_READ;
424 case TWR_DS18B20_STATE_READ:
426 self->_state = TWR_DS18B20_STATE_ERROR;
428 uint8_t scratchpad[_TWR_DS18B20_SCRATCHPAD_SIZE];
430 for (
int i = 0; i <
self->_sensor_found; i++)
450 if (!_twr_ds18b20_is_scratchpad_valid(scratchpad))
455 self->_sensor[i]._temperature_raw = ((int16_t) scratchpad[1]) << 8 | ((int16_t) scratchpad[0]);
456 self->_sensor[i]._temperature_valid =
true;
459 if (!_twr_ds18b20_power_down(
self))
464 self->_state = TWR_DS18B20_STATE_UPDATE;
468 case TWR_DS18B20_STATE_UPDATE:
470 self->_measurement_active =
false;
472 self->_state = TWR_DS18B20_STATE_READY;
474 for (
int i = 0; i <
self->_sensor_found; i++)
476 if (self->_event_handler != NULL)
486 self->_state = TWR_DS18B20_STATE_ERROR;
Channel operates as input.
void twr_scheduler_plan_relative(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to tick relative from current spin.
bool twr_ds18b20_measure(twr_ds18b20_t *self)
Start measurement manually.
void twr_ds18b20_init_multiple(twr_ds18b20_t *self, twr_ds18b20_sensor_t *sensors, int sensor_count, twr_ds18b20_resolution_bits_t resolution)
Initialize multiple ds18b20 over channel B on Sensor Module.
void twr_ds18b20_set_update_interval(twr_ds18b20_t *self, twr_tick_t interval)
Set measurement interval.
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
bool twr_onewire_transaction_stop(twr_onewire_t *self)
Stop transaction.
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
bool twr_onewire_search_next(twr_onewire_t *self, uint64_t *device_number)
Manual search of next device.
bool twr_module_sensor_init(void)
Initialize Sensor Module.
uint8_t twr_onewire_crc8(const void *buffer, size_t length, uint8_t crc)
Calculate 8-bit CRC.
void twr_ds18b20_init(twr_ds18b20_t *self, twr_onewire_t *onewire, twr_ds18b20_sensor_t *sensors, int sensor_count, twr_ds18b20_resolution_bits_t resolution)
Initialize ds18b20.
bool twr_onewire_transaction_start(twr_onewire_t *self)
Start transaction, enable pll and run timer.
twr_module_sensor_revision_t twr_module_sensor_get_revision(void)
Get Sensor Module revision.
void twr_ds18b20_init_single(twr_ds18b20_t *self, twr_ds18b20_resolution_bits_t resolution)
Initialize single ds18b20 over channel B on Sensor Module.
bool twr_ds18b20_get_temperature_celsius(twr_ds18b20_t *self, uint64_t device_address, float *celsius)
Get measured temperature in degrees of Celsius.
void twr_module_sensor_set_mode(twr_module_sensor_channel_t channel, twr_module_sensor_mode_t mode)
Set output mode of Sensor Module channel.
int twr_ds18b20_get_sensor_found(twr_ds18b20_t *self)
Get number of found sensor.
void twr_ds18b20_set_power_dynamic(twr_ds18b20_t *self, bool on)
Set power dynamic, Turns VDD on and pull 4k7 only for measurement.
bool twr_module_sensor_set_pull(twr_module_sensor_channel_t channel, twr_module_sensor_pull_t pull)
Set pull of Sensor Module channel.
void twr_onewire_write_byte(twr_onewire_t *self, uint8_t data)
Select device.
void twr_onewire_read(twr_onewire_t *self, void *buffer, size_t length)
Select device.
void twr_ds18b20_set_event_handler(twr_ds18b20_t *self, void(*event_handler)(twr_ds18b20_t *, uint64_t _device_address, twr_ds18b20_event_t, void *), void *event_param)
Set callback function.
void twr_scheduler_plan_current_from_now(twr_tick_t tick)
Schedule current task to tick relative from now.
void twr_onewire_select(twr_onewire_t *self, uint64_t *device_number)
Select device.
void twr_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
bool twr_module_sensor_onewire_power_up(void)
Semaphore for 1Wire Power up: for R1.1 set VDD On, for R1.0 pull up 56R on channel A...
struct twr_onewire_t twr_onewire_t
1-Wire instance
void twr_onewire_search_start(twr_onewire_t *self, uint8_t family_code)
Start of manual search, see also twr_onewire_search_next.
void twr_onewire_skip_rom(twr_onewire_t *self)
Skip ROM.
bool twr_ds18b20_get_temperature_raw(twr_ds18b20_t *self, uint64_t device_address, int16_t *raw)
Get measured temperature in degrees of Celsius.
uint64_t twr_tick_t
Timestamp data type.
uint64_t twr_ds182b0_get_short_address(twr_ds18b20_t *self, uint8_t index)
Get device index by its device address.
bool twr_module_sensor_set_vdd(bool on)
Set VDD On / Off.
int twr_ds18b20_get_index_by_device_address(twr_ds18b20_t *self, uint64_t device_address)
Get device index by its device address.
bool twr_onewire_reset(twr_onewire_t *self)
Reset the 1-Wire bus and return the presence of any device.
twr_ds18b20_event_t
Callback events.
void twr_onewire_write(twr_onewire_t *self, const void *buffer, size_t length)
Select device.
#define TWR_TICK_INFINITY
Maximum timestamp value.
void twr_scheduler_plan_absolute(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to absolute tick.
twr_onewire_t * twr_module_sensor_get_onewire(void)
Initialize and get Instance 1-Wire for channel B.
struct twr_ds18b20_t twr_ds18b20_t
BigClown ds18b20 instance.