Browse Source

Make ROM code a byte array rather than platform-specific integer type.

main
David Antliff 8 years ago
parent
commit
513a747d6d
  1. 15
      main/ds18b20.c
  2. 3
      main/ds18b20.h
  3. 30
      main/ds18b20_main.c
  4. 72
      main/owb.c
  5. 40
      main/owb.h

15
main/ds18b20.c

@ -15,7 +15,7 @@
#include "ds18b20.h" #include "ds18b20.h"
#include "owb.h" #include "owb.h"
#define TAG "ds18b20" static const char * TAG = "ds18b20";
// Function commands // Function commands
@ -32,7 +32,7 @@ struct _DS18B20_Info
bool init; bool init;
bool use_crc; bool use_crc;
OneWireBus * bus; OneWireBus * bus;
uint64_t rom_code; OneWireBus_ROMCode rom_code;
}; };
static bool _is_init(const DS18B20_Info * ds18b20_info) 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) if (ds18b20_info != NULL)
{ {
@ -146,14 +146,7 @@ float ds18b20_get_temp(DS18B20_Info * ds18b20_info)
temp_LSB = buffer[0]; temp_LSB = buffer[0];
temp_MSB = buffer[1]; temp_MSB = buffer[1];
uint8_t crc = 0; if (owb_crc8_bytes(0, buffer, 9) != 0)
for (int i = 0; i < 9; ++i)
{
crc = owb_crc8(crc, buffer[i]);
}
ESP_LOGD(TAG, "crc 0x%02x", crc);
if (crc != 0)
{ {
ESP_LOGE(TAG, "CRC failed"); ESP_LOGE(TAG, "CRC failed");
temp_LSB = temp_MSB = 0; temp_LSB = temp_MSB = 0;

3
main/ds18b20.h

@ -28,8 +28,9 @@ void ds18b20_free(DS18B20_Info ** ds18b20_info);
* @brief Initialise a device info instance with the specified GPIO. * @brief Initialise a device info instance with the specified GPIO.
* @param[in] ds18b20_info Pointer to device info instance. * @param[in] ds18b20_info Pointer to device info instance.
* @param[in] bus Pointer to initialised 1-Wire bus 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. * @brief Enable or disable use of CRC checks on device communications.

30
main/ds18b20_main.c

@ -3,6 +3,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_log.h"
// Uncomment to enable static (stack-based) allocation of instances and avoid malloc/free. // Uncomment to enable static (stack-based) allocation of instances and avoid malloc/free.
//#define USE_STATIC 1 //#define USE_STATIC 1
@ -22,6 +23,8 @@
void app_main() void app_main()
{ {
esp_log_level_set("*", ESP_LOG_INFO); // set all components to INFO level
// Create a 1-Wire bus // Create a 1-Wire bus
#ifdef USE_STATIC #ifdef USE_STATIC
OneWireBus_Static owb_static; // static allocation OneWireBus_Static owb_static; // static allocation
@ -34,19 +37,20 @@ void app_main()
owb_use_crc(owb, true); // enable CRC check for ROM code owb_use_crc(owb, true); // enable CRC check for ROM code
// find all connected devices // 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; int num_devices = 0;
OneWireBus_SearchState search_state = {0}; OneWireBus_SearchState search_state = {0};
bool found = owb_search_first(owb, &search_state); bool found = owb_search_first(owb, &search_state);
while (found) while (found)
{ {
printf("Device %d found: ", num_devices); printf(" %d : ", num_devices);
for (int i = 7; i >= 0; i--) for (int i = 7; i >= 0; i--)
{ {
device_rom_codes[num_devices][i] = search_state.rom_code[i]; printf("%02x", ((uint8_t *)(&search_state.rom_code))[i]);
printf("%02x", search_state.rom_code[i]);
} }
printf("\n"); printf("\n");
device_rom_codes[num_devices] = search_state.rom_code;
++num_devices; ++num_devices;
found = owb_search_next(owb, &search_state); found = owb_search_next(owb, &search_state);
} }
@ -80,24 +84,26 @@ void app_main()
DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation
devices[i] = ds18b20_info; devices[i] = ds18b20_info;
#endif #endif
uint64_t rom_code = 0; // uint64_t rom_code = 0;
for (int j = 7; j >= 0; --j) // for (int j = 7; j >= 0; --j)
{ // {
rom_code |= ((uint64_t)device_rom_codes[i][j] << (8 * j)); // rom_code |= ((uint64_t)device_rom_codes[i][j] << (8 * j));
} // }
printf("1-Wire ROM code 0x%08" PRIx64 "\n", rom_code); // 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, 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_init_solo(ds18b20_info, owb); // only one device on bus
ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings
} }
while (1) while (1)
{ {
printf("\nTemperature readings (degrees C):\n");
for (int i = 0; i < num_devices; ++i) for (int i = 0; i < num_devices; ++i)
{ {
float temp = ds18b20_get_temp(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); vTaskDelay(1000 / portTICK_PERIOD_MS);
} }

72
main/owb.c

@ -10,7 +10,7 @@
#include "owb.h" #include "owb.h"
#include "owb_static.h" #include "owb_static.h"
#define TAG "owb" static const char * TAG = "owb";
struct _OneWireBus_Timing struct _OneWireBus_Timing
{ {
@ -235,6 +235,17 @@ static uint8_t _calc_crc(uint8_t crc, uint8_t data)
return table[crc ^ 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) static bool _search(const OneWireBus * bus, OneWireBus_SearchState * state)
{ {
// Based on https://www.maximintegrated.com/en/app-notes/index.mvp/id/187 // 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 // if this discrepancy if before the Last Discrepancy
// on a previous next then pick the same as last time // on a previous next then pick the same as last time
if (id_bit_number < state->last_discrepancy) 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 else
// if equal to last pick 1, if not then pick 0 // if equal to last pick 1, if not then pick 0
search_direction = (id_bit_number == state->last_discrepancy); 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 // set or clear the bit in the ROM byte rom_byte_number
// with mask rom_byte_mask // with mask rom_byte_mask
if (search_direction == 1) if (search_direction == 1)
state->rom_code[rom_byte_number] |= rom_byte_mask; state->rom_code.bytes[rom_byte_number] |= rom_byte_mask;
else 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 // serial number search direction write bit
_write_bit(bus, search_direction); _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 the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
if (rom_byte_mask == 0) 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_number++;
rom_byte_mask = 1; 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 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_discrepancy = 0;
state->last_device_flag = false; state->last_device_flag = false;
@ -416,42 +427,25 @@ int owb_rom_search(OneWireBus * bus)
return 0; 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 (_is_init(bus))
{ {
if (_reset(bus)) if (_reset(bus))
{ {
uint8_t buffer[8] = { 0 };
_write_byte(bus, OWB_ROM_READ); _write_byte(bus, OWB_ROM_READ);
_read_block(bus, buffer, 8); _read_block(bus, rom_code.bytes, sizeof(rom_code));
// device provides LSB first
for (int i = 7; i >= 0; --i)
{
// watch out for integer promotion
rom_code |= ((uint64_t)buffer[i] << (8 * i));
}
if (bus->use_crc) if (bus->use_crc)
{ {
// check CRC if (owb_crc8_bytes(0, rom_code.bytes, sizeof(rom_code)) != 0)
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)
{ {
ESP_LOGE(TAG, "CRC failed"); 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 else
{ {
@ -486,29 +480,27 @@ const uint8_t * owb_write_bytes(const OneWireBus * bus, const uint8_t * buffer,
return _write_block(bus, buffer, len); 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}; _write_block(bus, (uint8_t *)&rom_code, sizeof(rom_code));
for (int i = 0; i < sizeof(buffer); ++i)
{
// LSB first
buffer[i] = rom_code & 0xFF;
rom_code >>= 8;
}
_write_block(bus, buffer, sizeof(buffer));
} }
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); 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 owb_search_first(const OneWireBus * bus, OneWireBus_SearchState * state)
{ {
bool result = false; bool result = false;
if (state != NULL) 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_discrepancy = 0;
state->last_family_discrepancy = 0; state->last_family_discrepancy = 0;
state->last_device_flag = false; state->last_device_flag = false;

40
main/owb.h

@ -16,9 +16,20 @@ extern "C" {
#define OWB_ROM_SKIP 0xCC #define OWB_ROM_SKIP 0xCC
#define OWB_ROM_SEARCH_ALARM 0xEC #define OWB_ROM_SEARCH_ALARM 0xEC
typedef struct _OneWireBus OneWireBus; 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. * @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); 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. * @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 // 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. * @brief Reset the 1-Wire bus.
@ -86,7 +97,7 @@ uint8_t owb_read_byte(const OneWireBus * bus);
* @param[in] len Number of bytes to read, must not exceed length of receive buffer. * @param[in] len Number of bytes to read, must not exceed length of receive buffer.
* @return Pointer to 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. * @brief Write a number of bytes to the 1-Wire bus.
@ -95,14 +106,14 @@ uint8_t owb_read_byte(const OneWireBus * bus);
* @param[in] len Number of bytes to write. * @param[in] len Number of bytes to write.
* @return Pointer to write buffer. * @return Pointer to write buffer.
*/ */
const uint8_t * owb_write_bytes(const OneWireBus * bus, const uint8_t * buffer, unsigned int len); 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. * @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] bus Pointer to initialised bus instance.
* @param[in] rom_code ROM code to write to bus. * @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. * @brief 1-Wire 8-bit CRC lookup.
@ -110,13 +121,17 @@ void owb_write_rom_code(const OneWireBus * bus, uint64_t rom_code);
* @param[in] data Byte to feed into CRC. * @param[in] data Byte to feed into CRC.
* @return Resultant CRC value. * @return Resultant CRC value.
*/ */
uint8_t owb_crc8(uint8_t crc, uint8_t data); 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 // Search API
struct OneWireBus_SearchState struct OneWireBus_SearchState
{ {
uint8_t rom_code[8]; OneWireBus_ROMCode rom_code;
int last_discrepancy; int last_discrepancy;
int last_family_discrepancy; int last_family_discrepancy;
int last_device_flag; int last_device_flag;
@ -126,6 +141,9 @@ typedef struct OneWireBus_SearchState OneWireBus_SearchState;
bool owb_search_first(const OneWireBus * bus, OneWireBus_SearchState * state); bool owb_search_first(const OneWireBus * bus, OneWireBus_SearchState * state);
bool owb_search_next(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 #ifdef __cplusplus

Loading…
Cancel
Save