Firmware SDK
twr_onewire.c
1 #include <twr_onewire.h>
2 #include <twr_error.h>
3 
4 static void _twr_onewire_lock(twr_onewire_t *self);
5 static void _twr_onewire_unlock(twr_onewire_t *self);
6 static void _twr_onewire_search_reset(twr_onewire_t *self);
7 static void _twr_onewire_search_target_setup(twr_onewire_t *self, uint8_t family_code);
8 static int _twr_onewire_search_devices(twr_onewire_t *self, uint64_t *device_list, size_t device_list_size);
9 
10 #define _TWR_ONEWIRE_CHECK_CALLBACK(X) if (X == NULL) twr_error(TWR_ERROR_CALLBACK)
11 
12 bool twr_onewire_init(twr_onewire_t *self, const twr_onewire_driver_t *driver, void *driver_ctx)
13 {
14  memset(self, 0, sizeof(*self));
15 
16  _TWR_ONEWIRE_CHECK_CALLBACK(driver->init);
17  _TWR_ONEWIRE_CHECK_CALLBACK(driver->enable);
18  _TWR_ONEWIRE_CHECK_CALLBACK(driver->disable);
19  _TWR_ONEWIRE_CHECK_CALLBACK(driver->reset);
20  _TWR_ONEWIRE_CHECK_CALLBACK(driver->write_bit);
21  _TWR_ONEWIRE_CHECK_CALLBACK(driver->read_bit);
22  _TWR_ONEWIRE_CHECK_CALLBACK(driver->write_byte);
23  _TWR_ONEWIRE_CHECK_CALLBACK(driver->read_byte);
24 
25  self->_driver = driver;
26  self->_driver_ctx = driver_ctx;
27 
28  return self->_driver->init(self->_driver_ctx);
29 }
30 
32 {
33  if (self->_lock_count != 0)
34  {
35  return false;
36  }
37 
38  _twr_onewire_lock(self);
39 
40  return true;
41 }
42 
44 {
45  _twr_onewire_unlock(self);
46 
47  return true;
48 }
49 
51 {
52  return self->_lock_count != 0;
53 }
54 
56 {
57  bool state;
58 
59  _twr_onewire_lock(self);
60 
61  state = self->_driver->reset(self->_driver_ctx);
62 
63  _twr_onewire_unlock(self);
64 
65  return state;
66 }
67 
68 void twr_onewire_select(twr_onewire_t *self, uint64_t *device_number)
69 {
70  _twr_onewire_lock(self);
71 
72  if (*device_number == TWR_ONEWIRE_DEVICE_NUMBER_SKIP_ROM)
73  {
74  self->_driver->write_byte(self->_driver_ctx, 0xCC);
75  }
76  else
77  {
78  self->_driver->write_byte(self->_driver_ctx, 0x55);
79 
80  for (size_t i = 0; i < sizeof(uint64_t); i++)
81  {
82  self->_driver->write_byte(self->_driver_ctx, ((uint8_t *) device_number)[i]);
83  }
84  }
85 
86  _twr_onewire_unlock(self);
87 }
88 
90 {
91  _twr_onewire_lock(self);
92  self->_driver->write_byte(self->_driver_ctx, 0xCC);
93  _twr_onewire_unlock(self);
94 }
95 
96 void twr_onewire_write(twr_onewire_t *self, const void *buffer, size_t length)
97 {
98  _twr_onewire_lock(self);
99  for (size_t i = 0; i < length; i++)
100  {
101  self->_driver->write_byte(self->_driver_ctx, ((uint8_t *) buffer)[i]);
102  }
103  _twr_onewire_unlock(self);
104 }
105 
106 void twr_onewire_read(twr_onewire_t *self, void *buffer, size_t length)
107 {
108  _twr_onewire_lock(self);
109  for (size_t i = 0; i < length; i++)
110  {
111  ((uint8_t *) buffer)[i] = self->_driver->read_byte(self->_driver_ctx);
112  }
113  _twr_onewire_unlock(self);
114 }
115 
116 void twr_onewire_write_byte(twr_onewire_t *self, uint8_t byte)
117 {
118  _twr_onewire_lock(self);
119  self->_driver->write_byte(self->_driver_ctx, byte);
120  _twr_onewire_unlock(self);
121 }
122 
124 {
125  _twr_onewire_lock(self);
126  uint8_t data = self->_driver->read_byte(self->_driver_ctx);
127  _twr_onewire_unlock(self);
128  return data;
129 }
130 
132 {
133  _twr_onewire_lock(self);
134  self->_driver->write_bit(self->_driver_ctx, bit & 0x01);
135  _twr_onewire_unlock(self);
136 }
137 
139 {
140  _twr_onewire_lock(self);
141  int bit = self->_driver->read_bit(self->_driver_ctx);
142  _twr_onewire_unlock(self);
143  return bit;
144 }
145 
146 int twr_onewire_search_all(twr_onewire_t *self, uint64_t *device_list, size_t device_list_size)
147 {
148  _twr_onewire_search_reset(self);
149 
150  return _twr_onewire_search_devices(self, device_list, device_list_size);
151 }
152 
153 int twr_onewire_search_family(twr_onewire_t *self, uint8_t family_code, uint64_t *device_list, size_t device_list_size)
154 {
155  _twr_onewire_search_target_setup(self, family_code);
156 
157  return _twr_onewire_search_devices(self, device_list, device_list_size);
158 }
159 
161 {
162  self->_auto_ds28e17_sleep_mode = on;
163 }
164 
165 uint8_t twr_onewire_crc8(const void *buffer, size_t length, uint8_t crc)
166 {
167  uint8_t *_buffer = (uint8_t *) buffer;
168  uint8_t inbyte;
169  uint8_t i;
170 
171  while (length--)
172  {
173  inbyte = *_buffer++;
174  for (i = 8; i; i--)
175  {
176  if ((crc ^ inbyte) & 0x01)
177  {
178  crc >>= 1;
179  crc ^= 0x8C;
180  }
181  else
182  {
183  crc >>= 1;
184  }
185  inbyte >>= 1;
186  }
187  }
188 
189  return crc;
190 }
191 
192 uint16_t twr_onewire_crc16(const void *buffer, size_t length, uint16_t crc)
193 {
194  static const uint8_t oddparity[16] =
195  { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
196 
197  uint16_t i;
198  for (i = 0; i < length; i++)
199  {
200  uint16_t cdata = ((uint8_t *) buffer)[i];
201  cdata = (cdata ^ crc) & 0xff;
202  crc >>= 8;
203 
204  if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4]) crc ^= 0xC001;
205 
206  cdata <<= 6;
207  crc ^= cdata;
208  cdata <<= 1;
209  crc ^= cdata;
210  }
211  return crc;
212 }
213 
214 void twr_onewire_search_start(twr_onewire_t *self, uint8_t family_code)
215 {
216  if (family_code != 0)
217  {
218  _twr_onewire_search_target_setup(self, family_code);
219  }
220  else
221  {
222  _twr_onewire_search_reset(self);
223  }
224 }
225 
226 bool twr_onewire_search_next(twr_onewire_t *self, uint64_t *device_number)
227 {
228  if (self->_last_device_flag)
229  {
230  return false;
231  }
232 
233  _twr_onewire_lock(self);
234  bool search_result = self->_driver->search_next(self->_driver_ctx, self, device_number);
235  _twr_onewire_unlock(self);
236  return search_result;
237 }
238 
239 static void _twr_onewire_lock(twr_onewire_t *self)
240 {
241  if ((self->_lock_count)++ == 0)
242  {
243  self->_driver->enable(self->_driver_ctx);
244  }
245 }
246 
247 static void _twr_onewire_unlock(twr_onewire_t *self)
248 {
249  if (self->_lock_count < 1) twr_error(TWR_ERROR_ERROR_UNLOCK);
250 
251  if (self->_lock_count == 1)
252  {
253  if (self->_auto_ds28e17_sleep_mode)
254  {
255  if (self->_driver->reset(self->_driver_ctx))
256  {
257  self->_driver->write_byte(self->_driver_ctx, 0xcc);
258  self->_driver->write_byte(self->_driver_ctx, 0x1e);
259  }
260  }
261 
262  self->_driver->disable(self->_driver_ctx);
263  }
264 
265  self->_lock_count--;
266 }
267 
268 static void _twr_onewire_search_reset(twr_onewire_t *self)
269 {
270  self->_last_discrepancy = 0;
271  self->_last_device_flag = false;
272  self->_last_family_discrepancy = 0;
273 }
274 
275 static void _twr_onewire_search_target_setup(twr_onewire_t *self, uint8_t family_code)
276 {
277  memset(self->_last_rom_no, 0, sizeof(self->_last_rom_no));
278  self->_last_rom_no[0] = family_code;
279  self->_last_discrepancy = 64;
280  self->_last_family_discrepancy = 0;
281  self->_last_device_flag = false;
282 }
283 
284 static int _twr_onewire_search_devices(twr_onewire_t *self, uint64_t *device_list, size_t device_list_size)
285 {
286  int devices = 0;
287  int max_devices = device_list_size / sizeof(uint64_t);
288 
289  while ((devices < max_devices) && twr_onewire_search_next(self, device_list))
290  {
291  device_list++;
292  devices++;
293  }
294 
295  return devices;
296 }
int twr_onewire_search_family(twr_onewire_t *self, uint8_t family_code, uint64_t *device_list, size_t device_list_size)
Search for all devices on 1-Wire with family code.
Definition: twr_onewire.c:153
bool twr_onewire_transaction_stop(twr_onewire_t *self)
Stop transaction.
Definition: twr_onewire.c:43
bool twr_onewire_search_next(twr_onewire_t *self, uint64_t *device_number)
Manual search of next device.
Definition: twr_onewire.c:226
uint8_t twr_onewire_crc8(const void *buffer, size_t length, uint8_t crc)
Calculate 8-bit CRC.
Definition: twr_onewire.c:165
uint8_t twr_onewire_read_byte(twr_onewire_t *self)
Select device.
Definition: twr_onewire.c:123
bool twr_onewire_transaction_start(twr_onewire_t *self)
Start transaction, enable pll and run timer.
Definition: twr_onewire.c:31
void twr_onewire_write_byte(twr_onewire_t *self, uint8_t byte)
Select device.
Definition: twr_onewire.c:116
void twr_onewire_read(twr_onewire_t *self, void *buffer, size_t length)
Select device.
Definition: twr_onewire.c:106
int twr_onewire_read_bit(twr_onewire_t *self)
Select device.
Definition: twr_onewire.c:138
void twr_onewire_write_bit(twr_onewire_t *self, int bit)
Select device.
Definition: twr_onewire.c:131
uint16_t twr_onewire_crc16(const void *buffer, size_t length, uint16_t crc)
Calculate 16-bit CRC, polynomial 0x8005.
Definition: twr_onewire.c:192
void twr_onewire_select(twr_onewire_t *self, uint64_t *device_number)
Select device.
Definition: twr_onewire.c:68
struct twr_onewire_t twr_onewire_t
1-Wire instance
Definition: twr_onewire.h:14
void twr_onewire_search_start(twr_onewire_t *self, uint8_t family_code)
Start of manual search, see also twr_onewire_search_next.
Definition: twr_onewire.c:214
void twr_onewire_skip_rom(twr_onewire_t *self)
Skip ROM.
Definition: twr_onewire.c:89
void twr_onewire_auto_ds28e17_sleep_mode(twr_onewire_t *self, bool on)
Enable call sleep mode for all ds28e17 after transaction.
Definition: twr_onewire.c:160
bool twr_onewire_is_transaction(twr_onewire_t *self)
Is transaction run.
Definition: twr_onewire.c:50
bool twr_onewire_init(twr_onewire_t *self, const twr_onewire_driver_t *driver, void *driver_ctx)
Initialize 1-Wire.
Definition: twr_onewire.c:12
int twr_onewire_search_all(twr_onewire_t *self, uint64_t *device_list, size_t device_list_size)
Search for all devices on 1-Wire.
Definition: twr_onewire.c:146
bool twr_onewire_reset(twr_onewire_t *self)
Reset the 1-Wire bus and return the presence of any device.
Definition: twr_onewire.c:55
void twr_onewire_write(twr_onewire_t *self, const void *buffer, size_t length)
Select device.
Definition: twr_onewire.c:96