code import

master
Ondřej Hruška 7 years ago
parent 97b33510d9
commit f7bcc754e4
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 6
      .gitignore
  2. 122
      main.c
  3. 92
      ow_search.c
  4. 92
      ow_search.h

6
.gitignore vendored

@ -0,0 +1,6 @@
cmake-build-debug/
.idea/
CMakeLists.txt
*.o
*.elf
*.out

122
main.c

@ -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…
Cancel
Save