parent
97b33510d9
commit
f7bcc754e4
@ -0,0 +1,6 @@ |
|||||||
|
cmake-build-debug/ |
||||||
|
.idea/ |
||||||
|
CMakeLists.txt |
||||||
|
*.o |
||||||
|
*.elf |
||||||
|
*.out |
@ -0,0 +1,122 @@ |
|||||||
|
#include <stdlib.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include <inttypes.h> |
||||||
|
|
||||||
|
#include "ow_search.h" |
||||||
|
|
||||||
|
// ----------- DEMO -----------------
|
||||||
|
|
||||||
|
void main(void) |
||||||
|
{ |
||||||
|
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_romcode_t addresses[4]; |
||||||
|
|
||||||
|
int x=0; |
||||||
|
while (search_state.status == OW_SEARCH_MORE) { |
||||||
|
uint16_t count = ow_search_run(&search_state, addresses, 4); |
||||||
|
printf("Found %d addresses, status %d\n", count, search_state.status); |
||||||
|
for(int i=0; i<count; 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); |
||||||
|
} |
||||||
|
printf("\n"); |
||||||
|
if(++x > 10) break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// ------------ SIMULATOR ---------------
|
||||||
|
|
||||||
|
struct owunit { |
||||||
|
ow_romcode_t romcode; |
||||||
|
bool selected; |
||||||
|
uint8_t rompos; |
||||||
|
int state; |
||||||
|
}; |
||||||
|
|
||||||
|
#define UNITS_COUNT 12 |
||||||
|
struct owunit units[UNITS_COUNT] = { |
||||||
|
{.romcode = {0b00000000}},//00
|
||||||
|
{.romcode = {0b00000001}},//01
|
||||||
|
{.romcode = {0b00010001}},//11
|
||||||
|
{.romcode = {0b00110001}},//31
|
||||||
|
{.romcode = {0b00110101}},//35
|
||||||
|
{.romcode = {0b01010001}},//51
|
||||||
|
{.romcode = {0b10000000}},//80
|
||||||
|
{.romcode = {0b10101010}},//aa
|
||||||
|
{.romcode = {0b11110101}},//f5
|
||||||
|
{.romcode = {0b11110111}},//f7
|
||||||
|
{.romcode = {0xFF,0x00,0xFF,0x00,0x55,0x00,0xAA,0x00}}, |
||||||
|
{.romcode = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}}, |
||||||
|
}; |
||||||
|
|
||||||
|
bool rom_device_reset(struct owunit *device) |
||||||
|
{ |
||||||
|
device->rompos = 0; |
||||||
|
device->state = 0; |
||||||
|
device->selected = true; |
||||||
|
} |
||||||
|
|
||||||
|
bool rom_device_read(struct owunit *device) |
||||||
|
{ |
||||||
|
if (!device->selected) return true; |
||||||
|
if (device->state == 0) { |
||||||
|
device->state++; |
||||||
|
bool res = ow_code_getbit(device->romcode, device->rompos); |
||||||
|
return res; |
||||||
|
} |
||||||
|
if (device->state == 1) { |
||||||
|
device->state++; |
||||||
|
bool res = !ow_code_getbit(device->romcode, device->rompos); |
||||||
|
return res; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void rom_device_write(struct owunit *device, bool selectedbit) |
||||||
|
{ |
||||||
|
if (!device->selected) return; |
||||||
|
|
||||||
|
if (ow_code_getbit(device->romcode, device->rompos) != selectedbit) { |
||||||
|
device->selected = false; |
||||||
|
} |
||||||
|
else { |
||||||
|
device->rompos++; |
||||||
|
device->state = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool ow_reset(void) |
||||||
|
{ |
||||||
|
for (int i = 0; i < UNITS_COUNT; ++i) { |
||||||
|
rom_device_reset(&units[i]); |
||||||
|
} |
||||||
|
return (UNITS_COUNT > 0); |
||||||
|
} |
||||||
|
|
||||||
|
bool ow_read_bit(void) |
||||||
|
{ |
||||||
|
bool bus = 1; |
||||||
|
for (int i = 0; i < UNITS_COUNT; ++i) { |
||||||
|
bus &= rom_device_read(&units[i]); |
||||||
|
} |
||||||
|
return bus; |
||||||
|
} |
||||||
|
|
||||||
|
void ow_write_bit(bool value) |
||||||
|
{ |
||||||
|
for (int i = 0; i < UNITS_COUNT; ++i) { |
||||||
|
rom_device_write(&units[i], value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void ow_write_u8(uint8_t value) |
||||||
|
{ |
||||||
|
// Dummy, do nothing
|
||||||
|
} |
@ -0,0 +1,92 @@ |
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2018/02/01.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "ow_search.h" |
||||||
|
|
||||||
|
void ow_search_init(struct ow_search_state *state, uint8_t command) |
||||||
|
{ |
||||||
|
state->prev_last_fork = 64; |
||||||
|
memset(&state->prev_code[0], 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) |
||||||
|
{ |
||||||
|
if (state->status != OW_SEARCH_MORE) return 0; |
||||||
|
|
||||||
|
uint16_t found_devices = 0; |
||||||
|
|
||||||
|
while (found_devices < capacity) { |
||||||
|
uint8_t index = 0; |
||||||
|
ow_romcode_t code = {}; |
||||||
|
int8_t last_fork = -1; |
||||||
|
|
||||||
|
// Start a new transaction. Devices respond to reset
|
||||||
|
if (!ow_reset()) { |
||||||
|
state->status = OW_SEARCH_FAILED; |
||||||
|
goto done; |
||||||
|
} |
||||||
|
// Send the search command (SEARCH_ROM, SEARCH_ALARM)
|
||||||
|
ow_write_u8(state->command); |
||||||
|
|
||||||
|
bool p, n; |
||||||
|
while (index != 64) { |
||||||
|
// Read a bit and its complement
|
||||||
|
p = ow_read_bit(); |
||||||
|
n = ow_read_bit(); |
||||||
|
|
||||||
|
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) { |
||||||
|
// 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
|
||||||
|
} |
||||||
|
else if (index == state->prev_last_fork) { |
||||||
|
p = 1; // both forks are now exhausted
|
||||||
|
} |
||||||
|
else { // a new fork
|
||||||
|
last_fork = index; |
||||||
|
} |
||||||
|
} |
||||||
|
else if (p && n) { |
||||||
|
// No devices left connected - this doesn't normally happen
|
||||||
|
state->status = OW_SEARCH_FAILED; |
||||||
|
goto done; |
||||||
|
} |
||||||
|
|
||||||
|
// All devices have a matching bit here, or it was resolved in a fork
|
||||||
|
if (p) ow_code_setbit(code, index); |
||||||
|
ow_write_bit(p); |
||||||
|
index++; |
||||||
|
} |
||||||
|
|
||||||
|
// Record a found address
|
||||||
|
for (int i = 0; i < 8; i++) { |
||||||
|
state->prev_code[i] = codes[found_devices][i] = code[i]; |
||||||
|
} |
||||||
|
found_devices++; |
||||||
|
|
||||||
|
// Stop condition
|
||||||
|
if (last_fork == -1) { |
||||||
|
state->status = OW_SEARCH_DONE; |
||||||
|
goto done; |
||||||
|
} |
||||||
|
|
||||||
|
state->prev_last_fork = last_fork; |
||||||
|
} |
||||||
|
done: |
||||||
|
state->first = false; |
||||||
|
return found_devices; |
||||||
|
} |
@ -0,0 +1,92 @@ |
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2018/02/01.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef OW_SEARCH_H |
||||||
|
#define OW_SEARCH_H |
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// External API functions for interfacing the bus
|
||||||
|
// Customize as needed (and also update calls in the search function)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the 1-wire bus |
||||||
|
* |
||||||
|
* @return presence pulse received |
||||||
|
*/ |
||||||
|
extern bool ow_reset(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a byte to the bus |
||||||
|
* |
||||||
|
* @param[in] value byte value |
||||||
|
*/ |
||||||
|
extern void ow_write_u8(uint8_t value); |
||||||
|
/**
|
||||||
|
* Write a bit to the 1-wire bus |
||||||
|
* |
||||||
|
* @param[in] value bit value |
||||||
|
*/ |
||||||
|
extern void ow_write_bit(bool value); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a bit from the 1-wire bus |
||||||
|
* |
||||||
|
* @return bit value |
||||||
|
*/ |
||||||
|
extern bool ow_read_bit(void); |
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Data type holding one 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))) |
||||||
|
|
||||||
|
/**
|
||||||
|
* States of the search algorithm |
||||||
|
*/ |
||||||
|
enum ow_search_result { |
||||||
|
OW_SEARCH_DONE = 0, |
||||||
|
OW_SEARCH_MORE = 1, |
||||||
|
OW_SEARCH_FAILED = 2, |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal state of the search algorithm. |
||||||
|
* Check status to see if more remain to be read or an error occurred. |
||||||
|
*/ |
||||||
|
struct ow_search_state { |
||||||
|
int8_t prev_last_fork; |
||||||
|
ow_romcode_t prev_code; |
||||||
|
uint8_t command; |
||||||
|
enum ow_search_result status; |
||||||
|
bool first; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Init the state search struct |
||||||
|
* |
||||||
|
* @param[out] state - inited struct |
||||||
|
* @param[in] command - command to send for requesting the search (e.g. SEARCH_ROM) |
||||||
|
*/ |
||||||
|
void ow_search_init(struct ow_search_state *state, uint8_t command); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a search of the 1-wire bus, with a state struct pre-inited |
||||||
|
* using ow_search_init(). |
||||||
|
* |
||||||
|
* Romcodes are stored in the byte arrays in a numerically ascending order. |
||||||
|
* |
||||||
|
* @param[in,out] state - search state, used for multiple calls with limited buffer size |
||||||
|
* @param[out] codes - buffer for found romcodes |
||||||
|
* @param[in] capacity - buffer capacity |
||||||
|
* @return number of romcodes found. Search status is stored in state->status |
||||||
|
*/ |
||||||
|
uint16_t ow_search_run(struct ow_search_state *state, ow_romcode_t *codes, uint16_t capacity); |
||||||
|
|
||||||
|
#endif //OW_SEARCH_H
|
Loading…
Reference in new issue