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. 32
      main/ds18b20_main.c
  4. 72
      main/owb.c
  5. 70
      main/owb.h

15
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;

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.
* @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.

32
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);
}

72
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;

70
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

Loading…
Cancel
Save