added checksum support

master
Ondřej Hruška 7 years ago
parent 0f86b3575c
commit bb00e90e24
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 5
      main.c
  2. 41
      ow_search.c
  3. 17
      ow_search.h

@ -16,7 +16,7 @@ int main(void)
// than could fit in the address buffer.
struct ow_search_state search_state;
ow_search_init(&search_state, 0xF0); // SEARCH_ROM
ow_search_init(&search_state, 0xF0 /* SEARCH_ROM */, false /* checksums */);
// Buffer for the found addresses - can have up to 65536 rows
// Keep in mind that each address uses 8 bytes
@ -57,7 +57,7 @@ struct owunit {
int state;
};
#define UNITS_COUNT 12
#define UNITS_COUNT 13
struct owunit units[UNITS_COUNT] = {
{.romcode = {0b00000000}},//00
{.romcode = {0b00000001}},//01
@ -71,6 +71,7 @@ struct owunit units[UNITS_COUNT] = {
{.romcode = {0b11110111}},//f7
{.romcode = {0xFF,0x00,0xFF,0x00,0x55,0x00,0xAA,0x00}},
{.romcode = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}},
{.romcode = {0x10,0x76,0xc7,0x04,0x01,0x08,0x00,0x71}}, // this is from a real 1-wire thermometer - checksum should be OK
};
void rom_device_reset(struct owunit *device)

@ -10,13 +10,47 @@
#include "ow_search.h"
void ow_search_init(struct ow_search_state *state, uint8_t command)
// -------- CHECKSUM --------
static inline uint8_t crc8_bits(uint8_t data)
{
uint8_t crc = 0;
if(data & 1) crc ^= 0x5e;
if(data & 2) crc ^= 0xbc;
if(data & 4) crc ^= 0x61;
if(data & 8) crc ^= 0xc2;
if(data & 0x10) crc ^= 0x9d;
if(data & 0x20) crc ^= 0x23;
if(data & 0x40) crc ^= 0x46;
if(data & 0x80) crc ^= 0x8c;
return crc;
}
static uint8_t crc8_add(uint8_t cksum, uint8_t byte)
{
return crc8_bits(byte ^ cksum);
}
uint8_t ow_checksum(const uint8_t *buff, uint16_t len)
{
uint8_t cksum = 0;
for(uint16_t i = 0; i < len; i++) {
cksum = crc8_add(cksum, buff[i]);
}
return cksum;
}
// -----------------------------
void ow_search_init(struct ow_search_state *state, uint8_t command, bool test_checksums)
{
state->prev_last_fork = 64;
memset(state->prev_code, 0, 8);
state->status = OW_SEARCH_MORE;
state->command = command;
state->first = true;
state->test_checksums = test_checksums;
}
uint16_t ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capacity)
@ -77,10 +111,13 @@ uint16_t ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint1
}
}
// Record a found address
memcpy(state->prev_code, code, 8);
if (!state->test_checksums || 0 == ow_checksum(code, 8)) {
// Record a found address
memcpy(codes[found_devices], code, 8);
found_devices++;
}
// Stop condition
if (last_fork == -1) {

@ -75,6 +75,7 @@ struct ow_search_state {
uint8_t command;
enum ow_search_result status;
bool first;
bool test_checksums;
};
/**
@ -82,8 +83,9 @@ struct ow_search_state {
*
* @param[out] state - inited struct
* @param[in] command - command to send for requesting the search (e.g. SEARCH_ROM)
* @param[in] test_checksums - verify checksums of all read romcodes
*/
void ow_search_init(struct ow_search_state *state, uint8_t command);
void ow_search_init(struct ow_search_state *state, uint8_t command, bool test_checksums);
/**
* Perform a search of the 1-wire bus, with a state struct pre-inited
@ -101,4 +103,17 @@ void ow_search_init(struct ow_search_state *state, uint8_t command);
*/
uint16_t ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capacity);
/**
* Compute a 1-wire type checksum.
* If the buffer includes the checksum, the result should be 0.
*
* (this function may be used externally, or you can delete the implementation
* from the c file if another implementation is already available)
*
* @param[in] buf - buffer of bytes to verify
* @param[in] len - buffer length
* @return checksum
*/
uint8_t ow_checksum(const uint8_t *buf, uint16_t len);
#endif //OW_SEARCH_H

Loading…
Cancel
Save