diff --git a/main/ds18b20.c b/main/ds18b20.c index 2c4113f..79637aa 100644 --- a/main/ds18b20.c +++ b/main/ds18b20.c @@ -15,7 +15,7 @@ #include "ds18b20.h" #include "owb.h" -#define TAG "ds18b20" +static const char * TAG = "ds18b20"; // Function commands @@ -32,7 +32,7 @@ struct _DS18B20_Info bool init; bool use_crc; OneWireBus * bus; - uint64_t rom_code; + OneWireBus_ROMCode rom_code; }; static bool _is_init(const DS18B20_Info * ds18b20_info) @@ -83,7 +83,7 @@ void ds18b20_free(DS18B20_Info ** ds18b20_info) } } -void ds18b20_init(DS18B20_Info * ds18b20_info, OneWireBus * bus, uint64_t rom_code) +void ds18b20_init(DS18B20_Info * ds18b20_info, OneWireBus * bus, OneWireBus_ROMCode rom_code) { if (ds18b20_info != NULL) { @@ -146,14 +146,7 @@ float ds18b20_get_temp(DS18B20_Info * ds18b20_info) temp_LSB = buffer[0]; temp_MSB = buffer[1]; - uint8_t crc = 0; - for (int i = 0; i < 9; ++i) - { - crc = owb_crc8(crc, buffer[i]); - } - ESP_LOGD(TAG, "crc 0x%02x", crc); - - if (crc != 0) + if (owb_crc8_bytes(0, buffer, 9) != 0) { ESP_LOGE(TAG, "CRC failed"); temp_LSB = temp_MSB = 0; diff --git a/main/ds18b20.h b/main/ds18b20.h index f5f4d34..75d488e 100644 --- a/main/ds18b20.h +++ b/main/ds18b20.h @@ -28,8 +28,9 @@ void ds18b20_free(DS18B20_Info ** ds18b20_info); * @brief Initialise a device info instance with the specified GPIO. * @param[in] ds18b20_info Pointer to device info instance. * @param[in] bus Pointer to initialised 1-Wire bus instance. + * @param[in] rom_code Device-specific ROM code to identify a device on the bus. */ -void ds18b20_init(DS18B20_Info * ds18b20_info, OneWireBus * bus, uint64_t rom_code); +void ds18b20_init(DS18B20_Info * ds18b20_info, OneWireBus * bus, OneWireBus_ROMCode rom_code); /** * @brief Enable or disable use of CRC checks on device communications. diff --git a/main/ds18b20_main.c b/main/ds18b20_main.c index f7aa57f..3db8ab1 100644 --- a/main/ds18b20_main.c +++ b/main/ds18b20_main.c @@ -3,6 +3,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" +#include "esp_log.h" // Uncomment to enable static (stack-based) allocation of instances and avoid malloc/free. //#define USE_STATIC 1 @@ -22,6 +23,8 @@ void app_main() { + esp_log_level_set("*", ESP_LOG_INFO); // set all components to INFO level + // Create a 1-Wire bus #ifdef USE_STATIC OneWireBus_Static owb_static; // static allocation @@ -34,19 +37,20 @@ void app_main() owb_use_crc(owb, true); // enable CRC check for ROM code // find all connected devices - uint8_t device_rom_codes[8][MAX_DEVICES] = {0}; + printf("Find devices:\n"); + OneWireBus_ROMCode device_rom_codes[MAX_DEVICES] = {0}; int num_devices = 0; OneWireBus_SearchState search_state = {0}; bool found = owb_search_first(owb, &search_state); while (found) { - printf("Device %d found: ", num_devices); + printf(" %d : ", num_devices); for (int i = 7; i >= 0; i--) { - device_rom_codes[num_devices][i] = search_state.rom_code[i]; - printf("%02x", search_state.rom_code[i]); + printf("%02x", ((uint8_t *)(&search_state.rom_code))[i]); } printf("\n"); + device_rom_codes[num_devices] = search_state.rom_code; ++num_devices; found = owb_search_next(owb, &search_state); } @@ -80,24 +84,26 @@ void app_main() DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation devices[i] = ds18b20_info; #endif - uint64_t rom_code = 0; - for (int j = 7; j >= 0; --j) - { - rom_code |= ((uint64_t)device_rom_codes[i][j] << (8 * j)); - } - printf("1-Wire ROM code 0x%08" PRIx64 "\n", rom_code); - - ds18b20_init(ds18b20_info, owb, rom_code); // associate with bus and device +// uint64_t rom_code = 0; +// for (int j = 7; j >= 0; --j) +// { +// rom_code |= ((uint64_t)device_rom_codes[i][j] << (8 * j)); +// } +// printf("1-Wire ROM code 0x%08" PRIx64 "\n", rom_code); + + //ds18b20_init(ds18b20_info, owb, rom_code); // associate with bus and device + ds18b20_init(ds18b20_info, owb, device_rom_codes[i]); // associate with bus and device //ds18b20_init_solo(ds18b20_info, owb); // only one device on bus ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings } while (1) { + printf("\nTemperature readings (degrees C):\n"); for (int i = 0; i < num_devices; ++i) { float temp = ds18b20_get_temp(devices[i]); - printf("Temp %d: %.1f degrees C\n", i, temp); + printf(" %d: %.2f\n", i, temp); } vTaskDelay(1000 / portTICK_PERIOD_MS); } diff --git a/main/owb.c b/main/owb.c index 50b025a..a627ca1 100644 --- a/main/owb.c +++ b/main/owb.c @@ -10,7 +10,7 @@ #include "owb.h" #include "owb_static.h" -#define TAG "owb" +static const char * TAG = "owb"; struct _OneWireBus_Timing { @@ -235,6 +235,17 @@ static uint8_t _calc_crc(uint8_t crc, uint8_t data) return table[crc ^ data]; } +static uint8_t _calc_crc_block(uint8_t crc, const uint8_t * buffer, size_t len) +{ + uint8_t crc8 = 0; + do + { + crc8 = _calc_crc(crc8, *buffer++); + } + while (len-- > 0); + return crc8; +} + static bool _search(const OneWireBus * bus, OneWireBus_SearchState * state) { // Based on https://www.maximintegrated.com/en/app-notes/index.mvp/id/187 @@ -288,7 +299,7 @@ static bool _search(const OneWireBus * bus, OneWireBus_SearchState * state) // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_number < state->last_discrepancy) - search_direction = ((state->rom_code[rom_byte_number] & rom_byte_mask) > 0); + search_direction = ((state->rom_code.bytes[rom_byte_number] & rom_byte_mask) > 0); else // if equal to last pick 1, if not then pick 0 search_direction = (id_bit_number == state->last_discrepancy); @@ -307,9 +318,9 @@ static bool _search(const OneWireBus * bus, OneWireBus_SearchState * state) // set or clear the bit in the ROM byte rom_byte_number // with mask rom_byte_mask if (search_direction == 1) - state->rom_code[rom_byte_number] |= rom_byte_mask; + state->rom_code.bytes[rom_byte_number] |= rom_byte_mask; else - state->rom_code[rom_byte_number] &= ~rom_byte_mask; + state->rom_code.bytes[rom_byte_number] &= ~rom_byte_mask; // serial number search direction write bit _write_bit(bus, search_direction); @@ -322,7 +333,7 @@ static bool _search(const OneWireBus * bus, OneWireBus_SearchState * state) // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask if (rom_byte_mask == 0) { - crc8 = _calc_crc(crc8, state->rom_code[rom_byte_number]); // accumulate the CRC + crc8 = _calc_crc(crc8, state->rom_code.bytes[rom_byte_number]); // accumulate the CRC rom_byte_number++; rom_byte_mask = 1; } @@ -345,7 +356,7 @@ static bool _search(const OneWireBus * bus, OneWireBus_SearchState * state) } // if no device found then reset counters so next 'search' will be like a first - if (!search_result || !state->rom_code[0]) + if (!search_result || !state->rom_code.bytes[0]) { state->last_discrepancy = 0; state->last_device_flag = false; @@ -416,42 +427,25 @@ int owb_rom_search(OneWireBus * bus) return 0; } -uint64_t owb_read_rom(const OneWireBus * bus) +OneWireBus_ROMCode owb_read_rom(const OneWireBus * bus) { - uint64_t rom_code = 0; + OneWireBus_ROMCode rom_code = {0}; if (_is_init(bus)) { if (_reset(bus)) { - uint8_t buffer[8] = { 0 }; _write_byte(bus, OWB_ROM_READ); - _read_block(bus, buffer, 8); - - // device provides LSB first - for (int i = 7; i >= 0; --i) - { - // watch out for integer promotion - rom_code |= ((uint64_t)buffer[i] << (8 * i)); - } + _read_block(bus, rom_code.bytes, sizeof(rom_code)); if (bus->use_crc) { - // check CRC - uint8_t crc = 0; - for (int i = 0; i < 8; ++i) - { - crc = _calc_crc(crc, buffer[i]); - } - ESP_LOGD(TAG, "crc 0x%02x", crc); - - if (crc != 0) + if (owb_crc8_bytes(0, rom_code.bytes, sizeof(rom_code)) != 0) { ESP_LOGE(TAG, "CRC failed"); - rom_code = 0; + memset(rom_code.bytes, 0, sizeof(rom_code)); } - - ESP_LOGD(TAG, "rom_code 0x%08" PRIx64, rom_code); } + ESP_LOGD(TAG, "rom_code %08" PRIx64, rom_code); } else { @@ -486,29 +480,27 @@ const uint8_t * owb_write_bytes(const OneWireBus * bus, const uint8_t * buffer, return _write_block(bus, buffer, len); } -void owb_write_rom_code(const OneWireBus * bus, uint64_t rom_code) +void owb_write_rom_code(const OneWireBus * bus, OneWireBus_ROMCode rom_code) { - uint8_t buffer[sizeof(uint64_t)] = {0}; - for (int i = 0; i < sizeof(buffer); ++i) - { - // LSB first - buffer[i] = rom_code & 0xFF; - rom_code >>= 8; - } - _write_block(bus, buffer, sizeof(buffer)); + _write_block(bus, (uint8_t *)&rom_code, sizeof(rom_code)); } -uint8_t owb_crc8(uint8_t crc, uint8_t data) +uint8_t owb_crc8_byte(uint8_t crc, uint8_t data) { return _calc_crc(crc, data); } +uint8_t owb_crc8_bytes(uint8_t crc, const uint8_t * data, size_t len) +{ + return _calc_crc_block(crc, data, len); +} + bool owb_search_first(const OneWireBus * bus, OneWireBus_SearchState * state) { bool result = false; if (state != NULL) { - memset(state->rom_code, 0, sizeof(state->rom_code)); + memset(&state->rom_code, 0, sizeof(state->rom_code)); state->last_discrepancy = 0; state->last_family_discrepancy = 0; state->last_device_flag = false; diff --git a/main/owb.h b/main/owb.h index 927e401..c1306f5 100644 --- a/main/owb.h +++ b/main/owb.h @@ -16,9 +16,20 @@ extern "C" { #define OWB_ROM_SKIP 0xCC #define OWB_ROM_SEARCH_ALARM 0xEC - typedef struct _OneWireBus OneWireBus; -typedef uint64_t OneWireBusROMCode; + +typedef union +{ + struct fields + { + uint8_t family[1]; // LSB - read/write first + uint8_t serial_number[6]; + uint8_t crc[1]; // MSB + } fields; + + uint8_t bytes[8]; + +} OneWireBus_ROMCode; /** * @brief Construct a new 1-Wire bus instance. @@ -49,14 +60,14 @@ void owb_init(OneWireBus * bus, int gpio); void owb_use_crc(OneWireBus * bus, bool use_crc); /** - * @brief Read 64-bit ROM code from device - only works when there is a single device on the bus. + * @brief Read ROM code from device - only works when there is a single device on the bus. * @param[in] bus Pointer to initialised bus instance. - * @return The 64-bit value read from the device's ROM. + * @return The value read from the device's ROM. */ -uint64_t owb_read_rom(const OneWireBus * bus); +OneWireBus_ROMCode owb_read_rom(const OneWireBus * bus); // TODO -bool owb_verify_rom(const OneWireBus * bus, uint64_t rom_code); +bool owb_verify_rom(const OneWireBus * bus, OneWireBus_ROMCode rom_code); /** * @brief Reset the 1-Wire bus. @@ -86,46 +97,53 @@ uint8_t owb_read_byte(const OneWireBus * bus); * @param[in] len Number of bytes to read, must not exceed length of receive buffer. * @return Pointer to receive buffer. */ - uint8_t * owb_read_bytes(const OneWireBus * bus, uint8_t * buffer, unsigned int len); +uint8_t * owb_read_bytes(const OneWireBus * bus, uint8_t * buffer, size_t len); - /** - * @brief Write a number of bytes to the 1-Wire bus. - * @param[in] bus Pointer to initialised bus instance. - * @param[in] buffer Pointer to buffer to write data from. - * @param[in] len Number of bytes to write. - * @return Pointer to write buffer. - */ -const uint8_t * owb_write_bytes(const OneWireBus * bus, const uint8_t * buffer, unsigned int len); +/** + * @brief Write a number of bytes to the 1-Wire bus. + * @param[in] bus Pointer to initialised bus instance. + * @param[in] buffer Pointer to buffer to write data from. + * @param[in] len Number of bytes to write. + * @return Pointer to write buffer. + */ +const uint8_t * owb_write_bytes(const OneWireBus * bus, const uint8_t * buffer, size_t len); /** * @brief Write a ROM code to the 1-Wire bus ensuring LSB is sent first. * @param[in] bus Pointer to initialised bus instance. * @param[in] rom_code ROM code to write to bus. */ -void owb_write_rom_code(const OneWireBus * bus, uint64_t rom_code); +void owb_write_rom_code(const OneWireBus * bus, OneWireBus_ROMCode rom_code); /** - * @brief 1-Wire 8-bit CRC lookup. - * @param[in] crc Starting CRC value. Pass in prior CRC to accumulate. - * @param[in] data Byte to feed into CRC. - * @return Resultant CRC value. - */ -uint8_t owb_crc8(uint8_t crc, uint8_t data); + * @brief 1-Wire 8-bit CRC lookup. + * @param[in] crc Starting CRC value. Pass in prior CRC to accumulate. + * @param[in] data Byte to feed into CRC. + * @return Resultant CRC value. + */ +uint8_t owb_crc8_byte(uint8_t crc, uint8_t data); + + +// TODO +uint8_t owb_crc8_bytes(uint8_t crc, const uint8_t * data, size_t len); // Search API struct OneWireBus_SearchState { - uint8_t rom_code[8]; - int last_discrepancy; - int last_family_discrepancy; - int last_device_flag; + OneWireBus_ROMCode rom_code; + int last_discrepancy; + int last_family_discrepancy; + int last_device_flag; }; typedef struct OneWireBus_SearchState OneWireBus_SearchState; bool owb_search_first(const OneWireBus * bus, OneWireBus_SearchState * state); bool owb_search_next(const OneWireBus * bus, OneWireBus_SearchState * state); +// TODO: maybe not useful? +uint64_t uint64_from_rom_code(OneWireBus_ROMCode rom_code); +OneWireBus_ROMCode rom_code_from_uint64(uint64_t rom_code); #ifdef __cplusplus