Firmware SDK
twr_ds2484.c
1 #include <twr_ds2484.h>
2 #include <twr_i2c.h>
3 #include <twr_gpio.h>
4 #include <twr_log.h>
5 #include <twr_delay.h>
6 
7 #define _TWR_DS2484_I2C_ADDRESS 0x18
8 
9 // command set
10 #define _TWR_DS2484_CMD_DRST (0xF0) // Device Reset
11 #define _TWR_DS2484_CMD_SRP (0xE1) // Set Read Pointer
12 #define _TWR_DS2484_CMD_WCFG (0xD2) // Write Configuration
13 #define _TWR_DS2484_CMD_CHSL (0xC3) // Channel Select(TWR_DS2484-800 only)
14 #define _TWR_DS2484_CMD_1WRS (0xB4) // 1-Wire Reset
15 #define _TWR_DS2484_CMD_1WSB (0x87) // 1-Wire Single Bit
16 #define _TWR_DS2484_CMD_1WWB (0xA5) // 1-Wire Write Byte
17 #define _TWR_DS2484_CMD_1WRB (0x96) // 1-Wire Read Byte
18 #define _TWR_DS2484_CMD_1WT (0x78) // 1-Wire Wire Triplet
19 
20 // register pointers
21 #define _TWR_DS2484_REG_ST (0xF0) // Status Register
22 #define _TWR_DS2484_REG_DATA (0xE1) // Data Register
23 #define _TWR_DS2484_REG_CFG (0xC3) // Configuration Register
24 
25 // status register TWR_DS2484_REG_STATUS_* in *.h file
26 
27 // configuration register _TWR_DS2484_REG_CFG
28 #define _TWR_DS2484_CFG_APU (1<<0) // Active Pullup(1==yes)
29 #define _TWR_DS2484_CFG_SPU (1<<2) // Strong Pullup(1==yes)
30 #define _TWR_DS2484_CFG_1WS (1<<3) // 1-Wire Speed(0==standard, 1==overdrive)
31 
32 #define _TWR_DS2484_CFG_DEFAULT (_TWR_DS2484_CFG_APU)
33 
34 static bool _twr_ds2484_i2c_read_byte(twr_ds2484_t *self, uint8_t *b);
35 static bool _twr_ds2484_i2c_write_byte(twr_ds2484_t *self, const uint8_t b);
36 static bool _twr_ds2484_device_reset(twr_ds2484_t *self);
37 static bool _twr_ds2484_write_config(twr_ds2484_t *self, const uint8_t cfg);
38 static bool _twr_ds2484_set_reed_pointer(twr_ds2484_t *self, uint8_t srp);
39 
41 {
42  memset(self, 0, sizeof(*self));
43 
44  self->_i2c_channel = i2c_channel;
45 
46  self->_ready = false;
47 
48  twr_i2c_init(self->_i2c_channel, TWR_I2C_SPEED_400_KHZ);
49 
50  return true;
51 }
52 
53 void twr_ds2484_set_slpz_handler(twr_ds2484_t *self, bool (*handler)(void *, bool), void *handler_ctx)
54 {
55  self->_set_slpz = handler;
56  self->_set_slpz_ctx = handler_ctx;
57 }
58 
60 {
61  self->_ready = false;
62 
63  if (self->_set_slpz != NULL)
64  {
65  if (!self->_set_slpz(self->_set_slpz_ctx, 1))
66  {
67  return;
68  }
69  }
70 
71  if (!_twr_ds2484_device_reset(self))
72  {
73  twr_log_error("TWR_DS2484: not detected");
74 
75  return;
76  }
77 
78  if (!_twr_ds2484_write_config(self, _TWR_DS2484_CFG_DEFAULT))
79  {
80  twr_log_error("TWR_DS2484: set config");
81 
82  return;
83  }
84 
85  self->_ready = true;
86 
87  return;
88 }
89 
91 {
93 
94  if (self->_set_slpz != NULL)
95  {
96  self->_set_slpz(self->_set_slpz_ctx, 0);
97  }
98 
99  self->_ready = false;
100 }
101 
103 {
104  if (!twr_ds2484_busy_wait(self))
105  {
106  return false;
107  }
108 
109  if (!_twr_ds2484_i2c_write_byte(self, _TWR_DS2484_CMD_1WRS))
110  {
111  return false;
112  }
113 
114  self->_srp = _TWR_DS2484_REG_ST;
115 
116  if (!twr_ds2484_busy_wait(self))
117  {
118  return false;
119  }
120 
121  // self->_search_ready = true;
122  return (self->_status & TWR_DS2484_STATUS_PPD) != 0;
123 }
124 
126 {
127  if (!self->_ready)
128  {
129  return false;
130  }
131 
132  int limit = 100;
133 
134  if (!_twr_ds2484_set_reed_pointer(self, _TWR_DS2484_REG_ST))
135  {
136  return false;
137  }
138 
139  while(limit--)
140  {
141  if (!_twr_ds2484_i2c_read_byte(self, &self->_status))
142  {
143  return false;
144  }
145 
146  if ((self->_status & TWR_DS2484_STATUS_1WB) == 0)
147  {
148  return true;
149  }
150 
151  twr_delay_us(1000);
152  }
153 
154  return false;
155 }
156 
157 bool twr_ds2484_write_byte(twr_ds2484_t *self, const uint8_t byte)
158 {
159  if (!twr_ds2484_busy_wait(self))
160  {
161  return false;
162  }
163 
164  if (!twr_i2c_memory_write_8b(self->_i2c_channel, _TWR_DS2484_I2C_ADDRESS, _TWR_DS2484_CMD_1WWB, byte))
165  {
166  return false;
167  }
168 
169  self->_srp = _TWR_DS2484_REG_ST;
170 
171  return true;
172 }
173 
174 bool twr_ds2484_read_byte(twr_ds2484_t *self, uint8_t *byte)
175 {
176  if (!twr_ds2484_busy_wait(self))
177  {
178  return false;
179  }
180 
181  if (!_twr_ds2484_i2c_write_byte(self, _TWR_DS2484_CMD_1WRB))
182  {
183  return false;
184  }
185 
186  self->_srp = _TWR_DS2484_REG_ST;
187 
188  if (!twr_ds2484_busy_wait(self))
189  {
190  return false;
191  }
192 
193  if (!_twr_ds2484_set_reed_pointer(self, _TWR_DS2484_REG_DATA))
194  {
195  return false;
196  }
197 
198  if (!_twr_ds2484_i2c_read_byte(self, byte))
199  {
200  return false;
201  }
202 
203  return true;
204 }
205 
206 bool twr_ds2484_read_bit(twr_ds2484_t *self, uint8_t *bit)
207 {
208  if (!twr_ds2484_busy_wait(self))
209  {
210  return false;
211  }
212 
213  if (!_twr_ds2484_i2c_write_byte(self, _TWR_DS2484_CMD_1WSB))
214  {
215  return false;
216  }
217 
218  self->_srp = _TWR_DS2484_REG_ST;
219 
220  if (!twr_ds2484_busy_wait(self))
221  {
222  return false;
223  }
224 
225  if (!_twr_ds2484_i2c_read_byte(self, bit))
226  {
227  return false;
228  }
229 
230  *bit = *bit & 0x80 ? 1 : 0;
231 
232  return true;
233 }
234 
235 bool twr_ds2484_triplet(twr_ds2484_t *self, const uint8_t direction)
236 {
237  if (!twr_ds2484_busy_wait(self))
238  {
239  return false;
240  }
241 
242  if (!twr_i2c_memory_write_8b(self->_i2c_channel, _TWR_DS2484_I2C_ADDRESS, _TWR_DS2484_CMD_1WT, direction ? 0x80 : 0))
243  {
244  return false;
245  }
246 
247  self->_srp = _TWR_DS2484_REG_ST;
248 
249  return true;
250 }
251 
252 bool twr_ds2484_is_ready(twr_ds2484_t *self)
253 {
254  return self->_ready;
255 }
256 
257 uint8_t twr_ds2484_status_get(twr_ds2484_t *self)
258 {
259  return self->_status;
260 }
261 
262 bool twr_ds2484_is_present(twr_ds2484_t *self)
263 {
264  return _twr_ds2484_device_reset(self);
265 }
266 
267 static bool _twr_ds2484_i2c_write_byte(twr_ds2484_t *self, const uint8_t b)
268 {
269  uint8_t buf[1];
270  twr_i2c_transfer_t transfer;
271 
272  transfer.device_address = _TWR_DS2484_I2C_ADDRESS;
273  buf[0] = b;
274  transfer.buffer = buf;
275  transfer.length = 1;
276 
277  return twr_i2c_write(self->_i2c_channel, &transfer);
278 }
279 
280 static bool _twr_ds2484_i2c_read_byte(twr_ds2484_t *self, uint8_t *b)
281 {
282  twr_i2c_transfer_t transfer;
283 
284  transfer.device_address = _TWR_DS2484_I2C_ADDRESS;
285  transfer.buffer = b;
286  transfer.length = 1;
287 
288  return twr_i2c_read(self->_i2c_channel, &transfer);
289 }
290 
291 static bool _twr_ds2484_device_reset(twr_ds2484_t *self)
292 {
293  if (!_twr_ds2484_i2c_write_byte(self, _TWR_DS2484_CMD_DRST))
294  {
295  return false;
296  }
297 
298  self->_srp = _TWR_DS2484_REG_ST;
299 
300  twr_delay_us(1000);
301 
302  return true;
303 }
304 
305 static bool _twr_ds2484_write_config(twr_ds2484_t *self, const uint8_t cfg)
306 {
307  uint8_t res;
308 
309  if (!twr_i2c_memory_write_8b(self->_i2c_channel, _TWR_DS2484_I2C_ADDRESS, _TWR_DS2484_CMD_WCFG, ((~cfg << 4) | cfg)))
310  {
311  return false;
312  }
313 
314  self->_srp = _TWR_DS2484_REG_CFG;
315 
316  if (!_twr_ds2484_i2c_read_byte(self, &res))
317  {
318  return false;
319  }
320 
321  if (res != cfg)
322  {
323  return false;
324  }
325 
326  self->_spu_on = (cfg & _TWR_DS2484_CFG_SPU) ? true : false;
327 
328  return true;
329 }
330 
331 static bool _twr_ds2484_set_reed_pointer(twr_ds2484_t *self, uint8_t srp)
332 {
333  if (self->_srp != srp)
334  {
335  if (!twr_i2c_memory_write_8b(self->_i2c_channel, _TWR_DS2484_I2C_ADDRESS, _TWR_DS2484_CMD_SRP, srp))
336  {
337  return false;
338  }
339  self->_srp = srp;
340  }
341  return true;
342 }
bool twr_i2c_write(twr_i2c_channel_t channel, const twr_i2c_transfer_t *transfer)
Write to I2C channel.
Definition: twr_i2c.c:243
void twr_ds2484_enable(twr_ds2484_t *self)
Enable DS2484.
Definition: twr_ds2484.c:59
#define TWR_DS2484_STATUS_1WB
Callback events.
Definition: twr_ds2484.h:12
bool twr_ds2484_reset(twr_ds2484_t *self)
Reset the 1-Wire bus and return the presence of any device.
Definition: twr_ds2484.c:102
uint8_t device_address
7-bit I2C device address
Definition: twr_i2c.h:45
void twr_delay_us(uint16_t microseconds)
Delay us.
Definition: twr_delay.c:5
I2C transfer parameters.
Definition: twr_i2c.h:42
void twr_ds2484_disable(twr_ds2484_t *self)
Disable DS2484.
Definition: twr_ds2484.c:90
void void void void void twr_log_error(const char *format,...) __attribute__((format(printf
Log ERROR message (annotated in log as <E>)
void twr_i2c_init(twr_i2c_channel_t channel, twr_i2c_speed_t speed)
Initialize I2C channel.
Definition: twr_i2c.c:57
struct twr_ds2484_t twr_ds2484_t
TMP112 instance.
Definition: twr_ds2484.h:23
bool twr_i2c_memory_write_8b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint8_t data)
Memory write 1 byte to I2C channel.
Definition: twr_i2c.c:408
size_t length
Length of buffer which is being written or read.
Definition: twr_i2c.h:51
twr_i2c_channel_t
I2C channels.
Definition: twr_i2c.h:15
bool twr_ds2484_init(twr_ds2484_t *self, twr_i2c_channel_t i2c_channel)
Initialize DS2484.
Definition: twr_ds2484.c:40
bool twr_i2c_read(twr_i2c_channel_t channel, const twr_i2c_transfer_t *transfer)
Read from I2C channel.
Definition: twr_i2c.c:289
void * buffer
Pointer to buffer which is being written or read.
Definition: twr_i2c.h:48
bool twr_ds2484_busy_wait(twr_ds2484_t *self)
Wait until not busy.
Definition: twr_ds2484.c:125
I2C communication speed is 400 kHz.
Definition: twr_i2c.h:36