From 711f2600ef4039cefdcb69c417c6667ddc3b9a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Thu, 1 Feb 2018 11:06:34 +0100 Subject: [PATCH] optimized and cleaned --- main.c | 34 ++++++++++++++++++++++++---------- ow_search.c | 25 +++++++++++++++---------- ow_search.h | 21 +++++++++++++++------ 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/main.c b/main.c index c7233e1..36a1497 100644 --- a/main.c +++ b/main.c @@ -10,30 +10,44 @@ void main(void) { + // The search algorithm stores its internal state in a struct. + + // This allows calling it repeatedly if there are more devices + // than could fit in the address buffer. + struct ow_search_state search_state; - ow_search_init(&search_state, 0xFF); // the real onewire search command will go here when used with real hw + ow_search_init(&search_state, 0xF0); // SEARCH_ROM - ow_romcode_t addresses[4]; + // Buffer for the found addresses - can have up to 65536 rows + // Keep in mind that each address uses 8 bytes + #define CODE_BUFFER_LEN 8 + ow_romcode_t addresses[CODE_BUFFER_LEN]; - int x=0; + // The algorithm stores its return value in the status field, + // we can loop until it becomes OW_SEARCH_DONE or OW_SEARCH_FAILED while (search_state.status == OW_SEARCH_MORE) { - uint16_t count = ow_search_run(&search_state, addresses, 4); + // Perform a run of the algorithm + uint16_t count = ow_search_run(&search_state, addresses, CODE_BUFFER_LEN); + + // Do something with the found addresses printf("Found %d addresses, status %d\n", count, search_state.status); - for(int i=0; i "); + for (int j = 0; j < 8; j++) { printf("%02x ", addresses[i][j]); } - printf("\n"); - uint64_t numeric = *((uint64_t*)(void*)&addresses[i][0]); - printf("n = 0x%016"PRIx64"\n", numeric); + uint64_t numeric = ow_romcode_to_u64(addresses[i]); + printf(" (0x%016"PRIx64")\n", numeric); } printf("\n"); - if(++x > 10) break; } } // ------------ SIMULATOR --------------- +// A simple 1-wire bus simulation following the real behavior of bus devices +// in the search operation. + struct owunit { ow_romcode_t romcode; bool selected; diff --git a/ow_search.c b/ow_search.c index 8b090a3..aca62be 100644 --- a/ow_search.c +++ b/ow_search.c @@ -1,5 +1,6 @@ // // Created by MightyPork on 2018/02/01. +// MIT license // #include @@ -12,14 +13,13 @@ void ow_search_init(struct ow_search_state *state, uint8_t command) { state->prev_last_fork = 64; - memset(&state->prev_code[0], 0, 8); + memset(state->prev_code, 0, 8); state->status = OW_SEARCH_MORE; state->command = command; state->first = true; } -uint16_t -ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capacity) +uint16_t ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capacity) { if (state->status != OW_SEARCH_MORE) return 0; @@ -38,6 +38,8 @@ ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capac // Send the search command (SEARCH_ROM, SEARCH_ALARM) ow_write_u8(state->command); + uint8_t *code_byte = &code[0]; + bool p, n; while (index != 64) { // Read a bit and its complement @@ -47,8 +49,7 @@ ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capac if (!p && !n) { // A fork: there are devices on the bus with different bit value // (the bus is open-drain, in both cases one device pulls it low) - if ((found_devices > 0 || !state->first) && - index < state->prev_last_fork) { + if ((found_devices > 0 || !state->first) && index < state->prev_last_fork) { // earlier than the last fork, take the same turn as before p = ow_code_getbit(state->prev_code, index); if (!p) last_fork = index; // remember for future runs, 1 not explored yet @@ -67,15 +68,18 @@ ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capac } // All devices have a matching bit here, or it was resolved in a fork - if (p) ow_code_setbit(code, index); + if (p) *code_byte |= (1 << (index & 7)); ow_write_bit(p); + index++; + if((index & 7) == 0) { + code_byte++; + } } // Record a found address - for (int i = 0; i < 8; i++) { - state->prev_code[i] = codes[found_devices][i] = code[i]; - } + memcpy(state->prev_code, code, 8); + memcpy(codes[found_devices], code, 8); found_devices++; // Stop condition @@ -86,7 +90,8 @@ ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capac state->prev_last_fork = last_fork; } - done: + +done: state->first = false; return found_devices; } diff --git a/ow_search.h b/ow_search.h index 8ce52ac..a7a6b2c 100644 --- a/ow_search.h +++ b/ow_search.h @@ -1,5 +1,6 @@ // -// Created by MightyPork on 2018/02/01. +// Created by MightyPork on 2018/02/01 +// MIT license // #ifndef OW_SEARCH_H @@ -39,13 +40,21 @@ extern bool ow_read_bit(void); // -------------------------------------------------------------------------------------- -/** Data type holding one romcode */ +/** + * Data type holding a romcode + */ typedef uint8_t ow_romcode_t[8]; -/** Get a bit from a romcode */ -#define ow_code_getbit(code, index) (bool)((code)[(index) / 8] & (1 << ((index) % 8))) -/** Set a bit to 1 in a romcode */ -#define ow_code_setbit(code, index) ((code)[(index) / 8] |= (1 << ((index) % 8))) +/** + * Get a single bit from a romcode + */ +#define ow_code_getbit(code, index) (bool)((code)[(index) >> 3] & (1 << ((index) & 7))) + +/** + * Convert to unsigned 64-bit integer + * (works only on little-endian systems - eg. OK on x86/x86_64, not on PowerPC) + */ +#define ow_romcode_to_u64(code) (*((uint64_t *) (void *)(code))) /** * States of the search algorithm