Arduino-OWI
One-Wire Interface (OWI) library for Arduino
OWI.h
Go to the documentation of this file.
1 
19 #ifndef OWI_H
20 #define OWI_H
21 
22 #ifndef CHARBITS
23 #define CHARBITS 8
24 #endif
25 
29 class OWI {
30 public:
32  static const size_t ROM_MAX = 8;
33 
35  static const size_t ROMBITS = ROM_MAX * CHARBITS;
36 
43  virtual bool reset() = 0;
44 
52  virtual uint8_t read(uint8_t bits = CHARBITS) = 0;
53 
62  bool read(void* buf, size_t count)
63  {
64  uint8_t* bp = (uint8_t*) buf;
65  uint8_t crc = 0;
66  while (count--) {
67  uint8_t value = read();
68  *bp++ = value;
69  crc = crc_update(crc, value);
70  }
71  return (crc == 0);
72  }
73 
81  virtual void write(uint8_t value, uint8_t bits = CHARBITS) = 0;
82 
90  void write(uint8_t cmd, const void* buf, size_t count)
91  {
92  write(cmd);
93  const uint8_t* bp = (const uint8_t*) buf;
94  while (count--) write(*bp++);
95  }
96 
106  virtual int8_t triplet(uint8_t& dir)
107  {
108  switch (read(2)) {
109  case 0b00:
110  write(dir, 1);
111  return (0b00);
112  case 0b01:
113  write(1, 1);
114  dir = 1;
115  return (0b01);
116  case 0b10:
117  write(0, 1);
118  dir = 0;
119  return (0b10);
120  default:
121  return (0b11);
122  }
123  }
124 
128  enum {
129  SEARCH_ROM = 0xF0,
130  READ_ROM = 0x33,
131  MATCH_ROM = 0x55,
132  SKIP_ROM = 0xCC,
133  ALARM_SEARCH = 0xEC,
134  LABEL_ROM = 0x15,
135  MATCH_LABEL = 0x51
136  } __attribute__((packed));
137 
146  static inline uint8_t crc_update(uint8_t crc, uint8_t data)
147  __attribute__((always_inline))
148  {
149  crc = crc ^ data;
150  for (uint8_t i = 0; i < 8; i++) {
151  if (crc & 0x01)
152  crc = (crc >> 1) ^ 0x8C;
153  else
154  crc >>= 1;
155  }
156  return (crc);
157  }
158 
166  static inline uint8_t crc(const void* buf, size_t count)
167  {
168  const uint8_t* bp = (const uint8_t*) buf;
169  uint8_t crc = 0;
170  while (count--) crc = crc_update(crc, *bp++);
171  return (crc);
172  }
173 
181  static inline uint8_t crc_P(const void* buf, size_t count)
182  {
183  const uint8_t* bp = (const uint8_t*) buf;
184  uint8_t crc = 0;
185  while (count--) crc = crc_update(crc, pgm_read_byte(bp++));
186  return (crc);
187  }
188 
190  enum {
191  FIRST = -1,
192  ERROR = -1,
193  LAST = ROMBITS
194  } __attribute__((packed));
195 
204  int8_t search_rom(uint8_t family, uint8_t* code, int8_t last = FIRST)
205  {
206  do {
207  if (!reset()) return (ERROR);
208  write(SEARCH_ROM);
209  last = search(code, last);
210  if (last == ERROR) return (ERROR);
211  } while ((last != LAST) && (family != 0) && (code[0] != family));
212  if (family != 0 && code[0] != family) return (ERROR);
213  return (last);
214  }
215 
222  bool read_rom(uint8_t* code)
223  {
224  if (!reset()) return (false);
225  write(READ_ROM);
226  return (read(code, ROM_MAX));
227  }
228 
236  bool match_rom(uint8_t* code)
237  {
238  if (!reset()) return (false);
239  write(MATCH_ROM, code, ROM_MAX);
240  return (true);
241  }
242 
248  bool skip_rom()
249  {
250  if (!reset()) return (false);
251  write(SKIP_ROM);
252  return (true);
253  }
254 
261  int8_t alarm_search(uint8_t* code, int8_t last = FIRST)
262  {
263  if (!reset()) return (ERROR);
265  return (search(code, last));
266  }
267 
274  bool match_label(uint8_t label)
275  {
276  if (!reset()) return (false);
278  write(label);
279  return (true);
280  }
281 
285  class Device {
286  public:
293  Device(OWI& owi, const uint8_t* rom = NULL) :
294  m_owi(owi)
295  {
296  if (rom != NULL) this->rom(rom);
297  }
298 
303  void rom(const uint8_t* rom)
304  {
305  uint8_t crc = 0;
306  for (size_t i = 0; i < ROM_MAX - 1; i++) {
307  uint8_t data = *rom++;
308  m_rom[i] = data;
309  crc = OWI::crc_update(crc, data);
310  }
311  m_rom[ROM_MAX - 1] = crc;
312  }
313 
318  void rom_P(const uint8_t* rom)
319  {
320  uint8_t crc = 0;
321  for (size_t i = 0; i < ROM_MAX - 1; i++) {
322  uint8_t data = pgm_read_byte(rom++);
323  m_rom[i] = data;
324  crc = OWI::crc_update(crc, data);
325  }
326  m_rom[ROM_MAX - 1] = crc;
327  }
328 
333  uint8_t* rom()
334  {
335  return (m_rom);
336  }
337 
338  protected:
341 
343  uint8_t m_rom[ROM_MAX];
344  };
345 
346 protected:
348  static const uint8_t RESET_RETRY_MAX = 4;
349 
357  int8_t search(uint8_t* code, int8_t last = FIRST)
358  {
359  uint8_t pos = 0;
360  int8_t next = LAST;
361  for (uint8_t i = 0; i < 8; i++) {
362  uint8_t data = 0;
363  for (uint8_t j = 0; j < 8; j++) {
364  uint8_t dir = (pos == last) || ((pos < last) && (code[i] & (1 << j)));
365  switch (triplet(dir)) {
366  case 0b00:
367  if (pos == last)
368  last = FIRST;
369  else if (pos > last || (code[i] & (1 << j)) == 0)
370  next = pos;
371  break;
372  case 0b11:
373  return (ERROR);
374  }
375  data >>= 1;
376  if (dir) data |= 0x80;
377  pos += 1;
378  }
379  code[i] = data;
380  }
381  return (next);
382  }
383 };
384 #endif
Definition: OWI.h:29
int8_t alarm_search(uint8_t *code, int8_t last=FIRST)
Definition: OWI.h:261
bool match_label(uint8_t label)
Definition: OWI.h:274
Error during search.
Definition: OWI.h:192
static const size_t ROMBITS
Definition: OWI.h:35
bool skip_rom()
Definition: OWI.h:248
static uint8_t crc_update(uint8_t crc, uint8_t data)
Definition: OWI.h:146
Broadcast or single device.
Definition: OWI.h:132
static const uint8_t RESET_RETRY_MAX
Definition: OWI.h:348
Select device with 8-bit short address.
Definition: OWI.h:135
void rom_P(const uint8_t *rom)
Definition: OWI.h:318
virtual int8_t triplet(uint8_t &dir)
Definition: OWI.h:106
uint8_t * rom()
Definition: OWI.h:333
static uint8_t crc(const void *buf, size_t count)
Definition: OWI.h:166
OWI & m_owi
Definition: OWI.h:340
int8_t search_rom(uint8_t family, uint8_t *code, int8_t last=FIRST)
Definition: OWI.h:204
virtual void write(uint8_t value, uint8_t bits=CHARBITS)=0
virtual bool reset()=0
Software::OWI< BOARD::D7 > owi
Definition: Alarm.ino:7
Set short address (8-bit).
Definition: OWI.h:134
int8_t search(uint8_t *code, int8_t last=FIRST)
Definition: OWI.h:357
Initiate device search.
Definition: OWI.h:129
bool read(void *buf, size_t count)
Definition: OWI.h:62
uint8_t m_rom[ROM_MAX]
Definition: OWI.h:343
static uint8_t crc_P(const void *buf, size_t count)
Definition: OWI.h:181
void rom(const uint8_t *rom)
Definition: OWI.h:303
#define CHARBITS
Definition: OWI.h:23
Select device with 64-bit rom code.
Definition: OWI.h:131
bool read_rom(uint8_t *code)
Definition: OWI.h:222
void write(uint8_t cmd, const void *buf, size_t count)
Definition: OWI.h:90
Last position, search completed.
Definition: OWI.h:193
bool match_rom(uint8_t *code)
Definition: OWI.h:236
Start position of search.
Definition: OWI.h:191
static const size_t ROM_MAX
Definition: OWI.h:32
virtual uint8_t read(uint8_t bits=CHARBITS)=0
Read device family code and serial number.
Definition: OWI.h:130
Initiate device alarm search.
Definition: OWI.h:133
Device(OWI &owi, const uint8_t *rom=NULL)
Definition: OWI.h:293