Firmware SDK
twr_zssc3123.c
1 #include <twr_zssc3123.h>
2 #include <twr_timer.h>
3 #include <twr_log.h>
4 
5 static uint8_t _twr_zssc3123_get_response(twr_zssc3123_t *self);
6 static void _twr_zssc3123_task(void *param);
7 
8 bool twr_zssc3123_init(twr_zssc3123_t *self, twr_i2c_channel_t i2c_channel, uint8_t i2c_address)
9 {
10  memset(self, 0, sizeof(*self));
11 
12  self->_i2c_channel = i2c_channel;
13  self->_i2c_address = i2c_address;
14 
16 
17  twr_i2c_init(self->_i2c_channel, TWR_I2C_SPEED_400_KHZ);
18 
19  self->_update_interval = TWR_TICK_INFINITY;
20 
21  self->_data_fetch_delay = 100;
22 
23  self->_task_id = twr_scheduler_register(_twr_zssc3123_task, self, TWR_TICK_INFINITY);
24 
25  return true;
26 }
27 
29 {
30  twr_i2c_deinit(self->_i2c_channel);
31 
32  twr_scheduler_unregister(self->_task_id);
33 
34  return true;
35 }
36 
38 {
39  self->_data_fetch_delay = interval;
40 }
41 
42 void twr_zssc3123_set_event_handler(twr_zssc3123_t *self, void (*event_handler)(twr_zssc3123_t *, twr_zssc3123_event_t, void *), void *event_param)
43 {
44  self->_event_handler = event_handler;
45  self->_event_param = event_param;
46 }
47 
49 {
50  self->_update_interval = interval;
51 
52  if (self->_update_interval == TWR_TICK_INFINITY)
53  {
54  if (!self->_measurement_active)
55  {
57  }
58  }
59  else
60  {
62  }
63 }
64 
66 {
67  if (self->_measurement_active)
68  {
69  return false;
70  }
71 
72  self->_measurement_active = true;
73 
74  twr_scheduler_plan_now(self->_task_id);
75 
76  return true;
77 }
78 
80 {
81  if (!self->_valid)
82  {
83  return false;
84  }
85 
86  *raw = self->_raw;
87 
88  return true;
89 }
90 
92 {
93  if (!twr_i2c_memory_write_16b(self->_i2c_channel, self->_i2c_address, 0xA0, 0x0000))
94  {
95  return false;
96  }
97 
98  return (_twr_zssc3123_get_response(self) >> 6) == 2;
99 }
100 
102 {
103  if (!twr_i2c_memory_write_16b(self->_i2c_channel, self->_i2c_address, 0x80, 0x0000))
104  {
105  return false;
106  }
107 
108  return true;
109 }
110 
111 bool twr_zssc3123_eeprom_read(twr_zssc3123_t *self, uint8_t adr, uint16_t *word)
112 {
113  if (!twr_i2c_memory_write_16b(self->_i2c_channel, self->_i2c_address, adr, 0x0000))
114  {
115  return false;
116  }
117 
118  twr_timer_start();
119 
120  twr_timer_delay(90);
121 
122  twr_timer_stop();
123 
124  uint8_t buffer[3];
125 
126  twr_i2c_transfer_t transfer;
127 
128  transfer.device_address = self->_i2c_address;
129 
130  transfer.buffer = buffer;
131 
132  transfer.length = sizeof(buffer);
133 
134  if (!twr_i2c_read(self->_i2c_channel, &transfer))
135  {
136  return false;
137 
138  }
139 
140  if ((buffer[0] & 0x03) != 1)
141  {
142  return false;
143  }
144 
145  *word = ((uint16_t) buffer[1]) << 8 | buffer[2];
146 
147  return true;
148 }
149 
150 bool twr_zssc3123_eeprom_write(twr_zssc3123_t *self, uint8_t address, uint16_t word)
151 {
152  if (!twr_i2c_memory_write_16b(self->_i2c_channel, self->_i2c_address, 0x40 + address, word))
153  {
154  return false;
155  }
156 
157  twr_timer_start();
158 
159  twr_timer_delay(12000);
160 
161  twr_timer_stop();
162 
163  return (_twr_zssc3123_get_response(self) & 0x03) == 1;
164 }
165 
167 {
168  if (!twr_i2c_memory_write_16b(self->_i2c_channel, self->_i2c_address, 0xa2, 0x0000))
169  {
170  return false;
171  }
172 
173  if (!twr_i2c_memory_write_16b(self->_i2c_channel, self->_i2c_address, 0xf0, 0x0021))
174  {
175  return false;
176  }
177 
178  return true;
179 }
180 
181 static uint8_t _twr_zssc3123_get_response(twr_zssc3123_t *self)
182 {
183  twr_i2c_transfer_t transfer;
184 
185  uint8_t data;
186 
187  transfer.device_address = self->_i2c_address;
188 
189  transfer.buffer = &data;
190 
191  transfer.length = 1;
192 
193  if (!twr_i2c_read(self->_i2c_channel, &transfer))
194  {
195  return 0xff;
196  }
197  else
198  {
199  return data;
200  }
201 }
202 
203 static bool _twr_zssc3123_data_fetch(twr_zssc3123_t *self)
204 {
205  twr_i2c_transfer_t transfer;
206 
207  uint8_t buffer[2];
208 
209  transfer.device_address = self->_i2c_address;
210 
211  transfer.buffer = buffer;
212 
213  transfer.length = sizeof(buffer);
214 
215  if (!twr_i2c_read(self->_i2c_channel, &transfer))
216  {
217  return false;
218  }
219 
220  if ((buffer[0] & 0xc0) == 0)
221  {
222  self->_valid = true;
223 
224  self->_raw = (uint16_t) (buffer[0] & 0x3f) << 8 | buffer[1];
225  }
226 
227  return true;
228 }
229 
230 static bool _twr_zssc3123_measurement_request(twr_zssc3123_t *self)
231 {
232  twr_i2c_transfer_t transfer;
233 
234  uint8_t buffer[1] = { self->_i2c_address << 1 };
235 
236  transfer.device_address = self->_i2c_address;
237 
238  transfer.buffer = buffer;
239 
240  transfer.length = sizeof(buffer);
241 
242  if (!twr_i2c_write(self->_i2c_channel, &transfer))
243  {
244  return false;
245  }
246 
247  return true;
248 }
249 
250 static void _twr_zssc3123_task(void *param)
251 {
252  twr_zssc3123_t *self = param;
253 
254 start:
255 
256  switch (self->_state)
257  {
258  case TWR_ZSSC3123_STATE_ERROR:
259  {
260  self->_valid = false;
261 
262  self->_measurement_active = false;
263 
264  if (self->_event_handler != NULL)
265  {
266  self->_event_handler(self, TWR_ZSSC3123_EVENT_ERROR, self->_event_param);
267  }
268 
269  self->_state = TWR_ZSSC3123_STATE_INITIALIZE;
270 
271  twr_scheduler_plan_current_absolute(self->_next_update_start);
272 
273  return;
274  }
275  case TWR_ZSSC3123_STATE_INITIALIZE:
276  {
277  self->_next_update_start = twr_tick_get() + self->_update_interval;
278 
279  if (!_twr_zssc3123_data_fetch(self))
280  {
281  self->_state = TWR_ZSSC3123_STATE_ERROR;
282 
283  goto start;
284  }
285 
286  self->_state = TWR_ZSSC3123_STATE_MEASURE;
287 
289 
290  return;
291  }
292  case TWR_ZSSC3123_STATE_MEASURE:
293  {
294  self->_next_update_start = twr_tick_get() + self->_update_interval;
295 
296  self->_measurement_active = true;
297 
298  self->_valid = false;
299 
300  if (!_twr_zssc3123_measurement_request(self))
301  {
302  self->_state = TWR_ZSSC3123_STATE_ERROR;
303 
304  goto start;
305  }
306 
307  self->_state = TWR_ZSSC3123_STATE_READ;
308 
309  twr_scheduler_plan_current_from_now(self->_data_fetch_delay);
310 
311  return;
312  }
313  case TWR_ZSSC3123_STATE_READ:
314  {
315  if (!_twr_zssc3123_data_fetch(self))
316  {
317  self->_state = TWR_ZSSC3123_STATE_ERROR;
318 
319  goto start;
320  }
321 
322  self->_measurement_active = false;
323 
324  self->_state = TWR_ZSSC3123_STATE_MEASURE;
325 
326  twr_scheduler_plan_current_absolute(self->_next_update_start);
327 
328  if (self->_event_handler != NULL)
329  {
330  self->_event_handler(self, TWR_ZSSC3123_EVENT_UPDATE, self->_event_param);
331  }
332 
333  return;
334  }
335  default:
336  {
337  self->_state = TWR_ZSSC3123_STATE_ERROR;
338 
339  goto start;
340  }
341  }
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
bool twr_zssc3123_eeprom_read(twr_zssc3123_t *self, uint8_t adr, uint16_t *word)
Write to eeprom, work only with command mode.
Definition: twr_zssc3123.c:111
bool twr_zssc3123_start_cm(twr_zssc3123_t *self)
Start Command Mode.
Definition: twr_zssc3123.c:91
bool twr_i2c_memory_write_16b(twr_i2c_channel_t channel, uint8_t device_address, uint32_t memory_address, uint16_t data)
Memory write 2 bytes to I2C channel.
Definition: twr_i2c.c:420
uint8_t device_address
7-bit I2C device address
Definition: twr_i2c.h:45
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
Definition: twr_scheduler.c:53
void twr_scheduler_plan_current_absolute(twr_tick_t tick)
Schedule current task to absolute tick.
I2C transfer parameters.
Definition: twr_i2c.h:42
bool twr_zssc3123_unlock_eeprom(twr_zssc3123_t *self)
Unlock eerpom, work only with command mode.
Definition: twr_zssc3123.c:166
void twr_timer_stop(void)
Stop timer.
Definition: twr_timer.c:42
bool twr_zssc3123_init(twr_zssc3123_t *self, twr_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize ZSSC3123.
Definition: twr_zssc3123.c:8
void twr_scheduler_plan_current_from_now(twr_tick_t tick)
Schedule current task to tick relative from now.
bool twr_zssc3123_end_cm(twr_zssc3123_t *self)
Ends Command Mode.
Definition: twr_zssc3123.c:101
bool twr_zssc3123_measure(twr_zssc3123_t *self)
Start measurement manually.
Definition: twr_zssc3123.c:65
void twr_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
struct twr_zssc3123_t twr_zssc3123_t
ZSSC3123 instance.
Definition: twr_zssc3123.h:25
void twr_i2c_init(twr_i2c_channel_t channel, twr_i2c_speed_t speed)
Initialize I2C channel.
Definition: twr_i2c.c:57
bool twr_zssc3123_deinit(twr_zssc3123_t *self)
Deitialize ZSSC3123.
Definition: twr_zssc3123.c:28
void twr_zssc3123_set_data_fetch_delay(twr_zssc3123_t *self, twr_tick_t interval)
Set data fetch delay.
Definition: twr_zssc3123.c:37
uint64_t twr_tick_t
Timestamp data type.
Definition: twr_tick.h:16
void twr_timer_init(void)
Initialize timer.
Definition: twr_timer.c:23
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
Definition: twr_tick.c:7
bool twr_zssc3123_get_raw_cap_data(twr_zssc3123_t *self, uint16_t *raw)
Get capacitance data as raw value.
Definition: twr_zssc3123.c:79
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
void twr_scheduler_unregister(twr_scheduler_task_id_t task_id)
Unregister specified task.
Definition: twr_scheduler.c:77
void twr_zssc3123_set_update_interval(twr_zssc3123_t *self, twr_tick_t interval)
Set scan interval.
Definition: twr_zssc3123.c:48
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
twr_zssc3123_event_t
Callback events.
Definition: twr_zssc3123.h:13
#define TWR_TICK_INFINITY
Maximum timestamp value.
Definition: twr_tick.h:12
void twr_scheduler_plan_absolute(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to absolute tick.
void twr_zssc3123_set_event_handler(twr_zssc3123_t *self, void(*event_handler)(twr_zssc3123_t *, twr_zssc3123_event_t, void *), void *event_param)
Set callback function.
Definition: twr_zssc3123.c:42
void twr_timer_delay(uint16_t microseconds)
Relative delay.
Definition: twr_timer.c:59
void twr_scheduler_plan_now(twr_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
void twr_timer_start(void)
Start timer.
Definition: twr_timer.c:28
void twr_i2c_deinit(twr_i2c_channel_t channel)
Deitialize I2C channel.
Definition: twr_i2c.c:140
I2C communication speed is 400 kHz.
Definition: twr_i2c.h:36
bool twr_zssc3123_eeprom_write(twr_zssc3123_t *self, uint8_t address, uint16_t word)
Read from eeprm, work only with command mode.
Definition: twr_zssc3123.c:150