Firmware SDK
twr_ds28e17.c
1 #include <twr_ds28e17.h>
2 #include <twr_tick.h>
3 #include <twr_log.h>
4 
5 static const twr_gpio_channel_t _twr_ds28e17_set_speed_lut[2] =
6 {
7  [TWR_I2C_SPEED_100_KHZ] = 0x00,
8  [TWR_I2C_SPEED_400_KHZ] = 0x01
9 };
10 
11 static bool _twr_ds28e17_write(twr_ds28e17_t *self, uint8_t *head, size_t head_length, void *buffer, size_t length);
12 static bool _twr_ds28e17_read(twr_ds28e17_t *self, uint8_t *head, size_t head_length, void *buffer, size_t length);
13 
14 void twr_ds28e17_init(twr_ds28e17_t *self, twr_onewire_t *onewire, uint64_t device_number)
15 {
16  memset(self, 0, sizeof(*self));
17 
18  self->_device_number = device_number;
19 
20  self->_onewire = onewire;
21 
22  twr_onewire_auto_ds28e17_sleep_mode(self->_onewire, true);
23 }
24 
26 {
27  (void) self;
28 }
29 
31 {
32  return self->_device_number;
33 }
34 
36 {
37  twr_onewire_transaction_start(self->_onewire);
38 
39  if (!twr_onewire_reset(self->_onewire))
40  {
41  twr_onewire_transaction_stop(self->_onewire);
42 
43  return false;
44  }
45 
46  twr_onewire_select(self->_onewire, &self->_device_number);
47 
48  uint8_t buffer[2];
49 
50  buffer[0] = 0xD2;
51  buffer[1] = _twr_ds28e17_set_speed_lut[speed];
52 
53  twr_onewire_write(self->_onewire, buffer, sizeof(buffer));
54 
55  twr_onewire_transaction_stop(self->_onewire);
56 
57  return true;
58 }
59 
61 {
62  uint8_t head[3];
63 
64  head[0] = 0x4B;
65  head[1] = transfer->device_address << 1;
66  head[2] = (uint8_t) transfer->length;
67 
68  return _twr_ds28e17_write(self, head, sizeof(head), transfer->buffer, transfer->length);
69 }
70 
72 {
73  uint8_t head[3];
74 
75  head[0] = 0x87;
76  head[1] = (transfer->device_address << 1) | 0x01;
77  head[2] = (uint8_t) transfer->length;
78 
79  return _twr_ds28e17_read(self, head, sizeof(head), transfer->buffer, transfer->length);
80 }
81 
83 {
84  size_t head_length;
85  uint8_t head[5];
86 
87  head[0] = 0x4B;
88  head[1] = transfer->device_address << 1;
89 
90  if ((transfer->memory_address & TWR_I2C_MEMORY_ADDRESS_16_BIT) != 0)
91  {
92  head_length = 5;
93  head[2] = (uint8_t) transfer->length + 2;
94  head[3] = transfer->memory_address >> 8;
95  head[4] = transfer->memory_address;
96  }
97  else
98  {
99  head_length = 4;
100  head[2] = (uint8_t) transfer->length + 1;
101  head[3] = (uint8_t) transfer->memory_address;
102  }
103 
104  return _twr_ds28e17_write(self, head, head_length, transfer->buffer, transfer->length);
105 }
106 
108 {
109  size_t head_length;
110  uint8_t head[6];
111 
112  head[0] = 0x2D;
113  head[1] = transfer->device_address << 1;
114 
115  if ((transfer->memory_address & TWR_I2C_MEMORY_ADDRESS_16_BIT) != 0)
116  {
117  head_length = 6;
118  head[2] = 2;
119  head[3] = transfer->memory_address >> 8;
120  head[4] = transfer->memory_address;
121  head[5] = transfer->length;
122  }
123  else
124  {
125  head_length = 5;
126  head[2] = 1;
127  head[3] = transfer->memory_address;
128  head[4] = transfer->length;
129  }
130 
131  return _twr_ds28e17_read(self, head, head_length, transfer->buffer, transfer->length);
132 }
133 
134 static bool _twr_ds28e17_write(twr_ds28e17_t *self, uint8_t *head, size_t head_length, void *buffer, size_t length)
135 {
136  twr_onewire_transaction_start(self->_onewire);
137 
138  twr_onewire_reset(self->_onewire);
139 
140  if (!twr_onewire_reset(self->_onewire))
141  {
142  twr_onewire_transaction_stop(self->_onewire);
143 
144  return false;
145  }
146 
147  uint16_t crc16 = twr_onewire_crc16(head, head_length, 0x00);
148 
149  crc16 = twr_onewire_crc16(buffer, length, crc16);
150 
151  twr_onewire_select(self->_onewire, &self->_device_number);
152 
153  twr_onewire_write(self->_onewire, head, head_length);
154 
155  twr_onewire_write(self->_onewire, buffer, length);
156 
157  crc16 = ~crc16;
158 
159  twr_onewire_write(self->_onewire, &crc16, sizeof(crc16));
160 
161  twr_tick_t timeout = twr_tick_get() + 50;
162 
163  while (twr_onewire_read_bit(self->_onewire) != 0)
164  {
165  if (timeout < twr_tick_get())
166  {
167  twr_onewire_transaction_stop(self->_onewire);
168 
169  return false;
170  }
171 
172  continue;
173  }
174 
175  uint8_t status = twr_onewire_read_byte(self->_onewire);
176 
177  uint8_t write_status = twr_onewire_read_byte(self->_onewire);
178 
179  twr_onewire_transaction_stop(self->_onewire);
180 
181  return (status == 0x00) && (write_status == 0x00);
182 }
183 
184 static bool _twr_ds28e17_read(twr_ds28e17_t *self, uint8_t *head, size_t head_length, void *buffer, size_t length)
185 {
186  twr_onewire_transaction_start(self->_onewire);
187 
188  twr_onewire_reset(self->_onewire);
189 
190  if (!twr_onewire_reset(self->_onewire))
191  {
192  twr_onewire_transaction_stop(self->_onewire);
193 
194  return false;
195  }
196 
197  uint16_t crc16 = twr_onewire_crc16(head, head_length, 0x00);
198 
199  twr_onewire_select(self->_onewire, &self->_device_number);
200 
201  twr_onewire_write(self->_onewire, head, head_length);
202 
203  crc16 = ~crc16;
204 
205  twr_onewire_write(self->_onewire, &crc16, sizeof(crc16));
206 
207  twr_tick_t timeout = twr_tick_get() + 50;
208 
209  while (twr_onewire_read_bit(self->_onewire) != 0)
210  {
211  if (timeout < twr_tick_get())
212  {
213  twr_onewire_transaction_stop(self->_onewire);
214 
215  return false;
216  }
217 
218  continue;
219  }
220 
221  uint8_t status = twr_onewire_read_byte(self->_onewire);
222 
223  uint8_t write_status = head[0] == 0x87 ? 0 : twr_onewire_read_byte(self->_onewire);
224 
225  if ((status != 0x00) || (write_status != 0x00))
226  {
227  twr_onewire_transaction_stop(self->_onewire);
228 
229  return false;
230  }
231 
232  twr_onewire_read(self->_onewire, buffer, length);
233 
234  twr_onewire_transaction_stop(self->_onewire);
235 
236  return true;
237 }
uint64_t twr_ds28e17_get_device_number(twr_ds28e17_t *self)
Get Device number.
Definition: twr_ds28e17.c:30
uint32_t memory_address
8-bit I2C memory address (it can be extended to 16-bit format if OR-ed with TWR_I2C_MEMORY_ADDRESS_16...
Definition: twr_i2c.h:63
I2C communication speed is 100 kHz.
Definition: twr_i2c.h:33
uint8_t device_address
7-bit I2C device address
Definition: twr_i2c.h:45
bool twr_onewire_transaction_stop(twr_onewire_t *self)
Stop transaction.
Definition: twr_onewire.c:43
bool twr_ds28e17_set_speed(twr_ds28e17_t *self, twr_i2c_speed_t speed)
Set I2C speed.
Definition: twr_ds28e17.c:35
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
I2C transfer parameters.
Definition: twr_i2c.h:42
bool twr_ds28e17_memory_write(twr_ds28e17_t *self, const twr_i2c_memory_transfer_t *transfer)
Memory write to I2C.
Definition: twr_ds28e17.c:82
void * buffer
Pointer to buffer which is being written or read.
Definition: twr_i2c.h:66
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
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
twr_gpio_channel_t
GPIO channels.
Definition: twr_gpio.h:12
twr_i2c_speed_t
I2C communication speed.
Definition: twr_i2c.h:30
struct twr_onewire_t twr_onewire_t
1-Wire instance
Definition: twr_onewire.h:14
I2C memory transfer parameters.
Definition: twr_i2c.h:57
uint64_t twr_tick_t
Timestamp data type.
Definition: twr_tick.h:16
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
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
Definition: twr_tick.c:7
size_t length
Length of buffer which is being written or read.
Definition: twr_i2c.h:51
bool twr_ds28e17_memory_read(twr_ds28e17_t *self, const twr_i2c_memory_transfer_t *transfer)
Memory read from I2C.
Definition: twr_ds28e17.c:107
void * buffer
Pointer to buffer which is being written or read.
Definition: twr_i2c.h:48
bool twr_ds28e17_write(twr_ds28e17_t *self, const twr_i2c_transfer_t *transfer)
Write to I2C.
Definition: twr_ds28e17.c:60
size_t length
Length of buffer which is being written or read.
Definition: twr_i2c.h:69
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
#define TWR_I2C_MEMORY_ADDRESS_16_BIT
This flag extends I2C memory transfer address from 8-bit to 16-bit.
Definition: twr_i2c.h:11
bool twr_ds28e17_read(twr_ds28e17_t *self, const twr_i2c_transfer_t *transfer)
Read from I2C.
Definition: twr_ds28e17.c:71
void twr_ds28e17_init(twr_ds28e17_t *self, twr_onewire_t *onewire, uint64_t device_number)
Initialize DS28E17.
Definition: twr_ds28e17.c:14
void twr_onewire_write(twr_onewire_t *self, const void *buffer, size_t length)
Select device.
Definition: twr_onewire.c:96
void twr_ds28e17_deinit(twr_ds28e17_t *self)
Deinitialize DS28E17.
Definition: twr_ds28e17.c:25
I2C communication speed is 400 kHz.
Definition: twr_i2c.h:36
uint8_t device_address
7-bit I2C device address
Definition: twr_i2c.h:60
DS28E17 instance.
Definition: twr_ds28e17.h:13