1 /**
2 ******************************************************************************
3 * @file ais25ba_reg.c
4 * @author Sensors Software Solution Team
5 * @brief AIS25BA driver file
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© Copyright (c) 2022 STMicroelectronics.
10 * All rights reserved.</center></h2>
11 *
12 * This software component is licensed by ST under BSD 3-Clause license,
13 * the "License"; You may not use this file except in compliance with the
14 * License. You may obtain a copy of the License at:
15 * opensource.org/licenses/BSD-3-Clause
16 *
17 ******************************************************************************
18 */
19
20 #include "ais25ba_reg.h"
21
22 /**
23 * @defgroup AIS25BA
24 * @brief This file provides a set of functions needed to drive the
25 * ais25ba enhanced inertial module.
26 * @{
27 *
28 */
29
30 /**
31 * @defgroup AIS25BA_Interfaces_Functions
32 * @brief This section provide a set of functions used to read and
33 * write a generic register of the device.
34 * MANDATORY: return 0 -> no Error.
35 * @{
36 *
37 */
38
39 /**
40 * @brief Read generic device register
41 *
42 * @param ctx communication interface handler.(ptr)
43 * @param reg first register address to read.
44 * @param data buffer for data read.(ptr)
45 * @param len number of consecutive register to read.
46 * @retval interface status (MANDATORY: return 0 -> no Error).
47 *
48 */
ais25ba_read_reg(const stmdev_ctx_t * ctx,uint8_t reg,uint8_t * data,uint16_t len)49 int32_t __weak ais25ba_read_reg(const stmdev_ctx_t *ctx, uint8_t reg,
50 uint8_t *data,
51 uint16_t len)
52 {
53 int32_t ret;
54
55 if (ctx == NULL) return -1;
56
57 ret = ctx->read_reg(ctx->handle, reg, data, len);
58
59 return ret;
60 }
61
62 /**
63 * @brief Write generic device register
64 *
65 * @param ctx communication interface handler.(ptr)
66 * @param reg first register address to write.
67 * @param data the buffer contains data to be written.(ptr)
68 * @param len number of consecutive register to write.
69 * @retval interface status (MANDATORY: return 0 -> no Error).
70 *
71 */
ais25ba_write_reg(const stmdev_ctx_t * ctx,uint8_t reg,uint8_t * data,uint16_t len)72 int32_t __weak ais25ba_write_reg(const stmdev_ctx_t *ctx, uint8_t reg,
73 uint8_t *data,
74 uint16_t len)
75 {
76 int32_t ret;
77
78 if (ctx == NULL) return -1;
79
80 ret = ctx->write_reg(ctx->handle, reg, data, len);
81
82 return ret;
83 }
84
85 /**
86 * @}
87 *
88 */
89
90 /**
91 * @defgroup AIS25BA_Private_functions
92 * @brief Section collect all the utility functions needed by APIs.
93 * @{
94 *
95 */
96
bytecpy(uint8_t * target,uint8_t * source)97 static void bytecpy(uint8_t *target, uint8_t *source)
98 {
99 if ((target != NULL) && (source != NULL))
100 {
101 *target = *source;
102 }
103 }
104
105 /**
106 * @}
107 *
108 */
109
110 /**
111 * @defgroup AIS25BA_Sensitivity
112 * @brief These functions convert raw-data into engineering units.
113 * @{
114 *
115 */
ais25ba_from_raw_to_mg(int16_t lsb)116 float_t ais25ba_from_raw_to_mg(int16_t lsb)
117 {
118 return ((float_t)lsb) * 0.122f;
119 }
120
121 /**
122 * @}
123 *
124 */
125
126 /**
127 * @defgroup Basic configuration
128 * @brief This section groups all the functions concerning
129 * device basic configuration.
130 * @{
131 *
132 */
133
134 /**
135 * @brief Device "Who am I".[get]
136 *
137 * @param ctx communication interface handler.(ptr)
138 * @param val ID values read from the I2C interface.
139 *
140 * @retval interface status (MANDATORY: return 0 -> no Error).
141 *
142 */
ais25ba_id_get(const stmdev_ctx_t * ctx,ais25ba_id_t * val)143 int32_t ais25ba_id_get(const stmdev_ctx_t *ctx, ais25ba_id_t *val)
144 {
145 int32_t ret = 0;
146
147 if (ctx != NULL)
148 {
149 ret = ais25ba_read_reg(ctx, AIS25BA_WHO_AM_I, (uint8_t *) & (val->id), 1);
150 }
151
152 return ret;
153 }
154
155 /**
156 * @brief Configures the bus operating mode.[set]
157 *
158 * @param ctx communication interface handler.(ptr)
159 * @param val configures the TDM bus operating mode.(ptr)
160 *
161 * @retval interface status (MANDATORY: return 0 -> no Error).
162 *
163 */
ais25ba_bus_mode_set(const stmdev_ctx_t * ctx,ais25ba_bus_mode_t * val)164 int32_t ais25ba_bus_mode_set(const stmdev_ctx_t *ctx,
165 ais25ba_bus_mode_t *val)
166 {
167 ais25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
168 ais25ba_tdm_cmax_h_t tdm_cmax_h;
169 ais25ba_tdm_cmax_l_t tdm_cmax_l;
170 uint8_t reg[2];
171 int32_t ret;
172
173 ret = ais25ba_read_reg(ctx, AIS25BA_TDM_CTRL_REG,
174 (uint8_t *)&tdm_ctrl_reg, 1);
175
176 if (ret == 0)
177 {
178 ret = ais25ba_read_reg(ctx, AIS25BA_TDM_CMAX_H, reg, 2);
179 bytecpy((uint8_t *)&tdm_cmax_h, ®[0]);
180 bytecpy((uint8_t *)&tdm_cmax_l, ®[1]);
181 tdm_ctrl_reg.tdm_pd = ~val->tdm.en;
182 tdm_ctrl_reg.data_valid = val->tdm.clk_pol;
183 tdm_ctrl_reg.delayed = val->tdm.clk_edge;
184 tdm_ctrl_reg.wclk_fq = val->tdm.mapping;
185 tdm_cmax_h.tdm_cmax = (uint8_t)(val->tdm.cmax / 256U);
186 tdm_cmax_l.tdm_cmax = (uint8_t)(val->tdm.cmax - tdm_cmax_h.tdm_cmax);
187 }
188
189 if (ret == 0)
190 {
191 ret = ais25ba_write_reg(ctx, AIS25BA_TDM_CTRL_REG,
192 (uint8_t *)&tdm_ctrl_reg, 1);
193 }
194
195 if (ret == 0)
196 {
197 bytecpy(®[0], (uint8_t *)&tdm_cmax_h);
198 bytecpy(®[1], (uint8_t *)&tdm_cmax_l);
199 ret = ais25ba_write_reg(ctx, AIS25BA_TDM_CMAX_H, reg, 2);
200 }
201
202 return ret;
203 }
204
205 /**
206 * @brief Get the bus operating mode.[get]
207 *
208 * @param ctx communication interface handler.(ptr)
209 * @param val configures the TDM bus operating mode.(ptr)
210 *
211 * @retval interface status (MANDATORY: return 0 -> no Error).
212 *
213 */
ais25ba_bus_mode_get(const stmdev_ctx_t * ctx,ais25ba_bus_mode_t * val)214 int32_t ais25ba_bus_mode_get(const stmdev_ctx_t *ctx,
215 ais25ba_bus_mode_t *val)
216 {
217 ais25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
218 ais25ba_tdm_cmax_h_t tdm_cmax_h;
219 ais25ba_tdm_cmax_l_t tdm_cmax_l;
220 uint8_t reg[2];
221 int32_t ret;
222
223 ret = ais25ba_read_reg(ctx, AIS25BA_TDM_CTRL_REG,
224 (uint8_t *)&tdm_ctrl_reg, 1);
225
226 if (ret == 0)
227 {
228 ret = ais25ba_read_reg(ctx, AIS25BA_TDM_CMAX_H, reg, 2);
229 bytecpy((uint8_t *)&tdm_cmax_h, ®[0]);
230 bytecpy((uint8_t *)&tdm_cmax_l, ®[1]);
231 }
232
233 val->tdm.en = ~tdm_ctrl_reg.tdm_pd;
234 val->tdm.clk_pol = tdm_ctrl_reg.data_valid;
235 val->tdm.clk_edge = tdm_ctrl_reg.delayed;
236 val->tdm.mapping = tdm_ctrl_reg.wclk_fq;
237 val->tdm.cmax = tdm_cmax_h.tdm_cmax * 256U;
238 val->tdm.cmax += tdm_cmax_l.tdm_cmax;
239
240 return ret;
241 }
242
243 /**
244 * @brief Sensor conversion parameters selection.[set]
245 *
246 * @param ctx communication interface handler.(ptr)
247 * @param val set the sensor conversion parameters by checking
248 * the constraints of the device.(ptr)
249 *
250 * @retval interface status (MANDATORY: return 0 -> no Error).
251 *
252 */
ais25ba_mode_set(const stmdev_ctx_t * ctx,ais25ba_md_t * val)253 int32_t ais25ba_mode_set(const stmdev_ctx_t *ctx, ais25ba_md_t *val)
254 {
255 ais25ba_axes_ctrl_reg_t axes_ctrl_reg;
256 ais25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
257 ais25ba_ctrl_reg_t ctrl_reg;
258 uint8_t reg[2];
259 int32_t ret;
260
261 ret = ais25ba_read_reg(ctx, AIS25BA_CTRL_REG_1, (uint8_t *)&ctrl_reg, 1);
262
263 if (ret == 0)
264 {
265 ret = ais25ba_read_reg(ctx, AIS25BA_TDM_CTRL_REG, reg, 2);
266 bytecpy((uint8_t *)&tdm_ctrl_reg, ®[0]);
267 bytecpy((uint8_t *)&axes_ctrl_reg, ®[1]);
268 }
269
270 ctrl_reg.pd = (uint8_t)val->xl.odr & 0x01U;
271 tdm_ctrl_reg.wclk_fq = ((uint8_t)val->xl.odr & 0x06U) >> 1;
272 axes_ctrl_reg.odr_auto_en = ((uint8_t)val->xl.odr & 0x10U) >> 4;
273
274 if (ret == 0)
275 {
276 ret = ais25ba_write_reg(ctx, AIS25BA_CTRL_REG_1, (uint8_t *)&ctrl_reg, 1);
277 }
278
279 /* writing checked configuration */
280 bytecpy(®[0], (uint8_t *)&tdm_ctrl_reg);
281 bytecpy(®[1], (uint8_t *)&axes_ctrl_reg);
282
283 if (ret == 0)
284 {
285 ret = ais25ba_write_reg(ctx, AIS25BA_TDM_CTRL_REG, (uint8_t *)®,
286 2);
287 }
288
289 return ret;
290 }
291
292 /**
293 * @brief Sensor conversion parameters selection.[get]
294 *
295 * @param ctx communication interface handler.(ptr)
296 * @param val get the sensor conversion parameters.(ptr)
297 *
298 * @retval interface status (MANDATORY: return 0 -> no Error).
299 *
300 */
ais25ba_mode_get(const stmdev_ctx_t * ctx,ais25ba_md_t * val)301 int32_t ais25ba_mode_get(const stmdev_ctx_t *ctx, ais25ba_md_t *val)
302 {
303 ais25ba_axes_ctrl_reg_t axes_ctrl_reg;
304 ais25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
305 ais25ba_ctrl_reg_t ctrl_reg;
306 uint8_t reg[2];
307 int32_t ret;
308
309 ret = ais25ba_read_reg(ctx, AIS25BA_CTRL_REG_1, (uint8_t *)&ctrl_reg, 1);
310
311 if (ret == 0)
312 {
313 ret = ais25ba_read_reg(ctx, AIS25BA_TDM_CTRL_REG, reg, 2);
314 bytecpy((uint8_t *)&tdm_ctrl_reg, ®[0]);
315 bytecpy((uint8_t *)&axes_ctrl_reg, ®[1]);
316 }
317
318 switch ((axes_ctrl_reg.odr_auto_en << 4) | (tdm_ctrl_reg.wclk_fq <<
319 1) |
320 ctrl_reg.pd)
321 {
322 case AIS25BA_XL_OFF:
323 val->xl.odr = AIS25BA_XL_OFF;
324 break;
325
326 case AIS25BA_XL_8kHz:
327 val->xl.odr = AIS25BA_XL_8kHz;
328 break;
329
330 case AIS25BA_XL_16kHz:
331 val->xl.odr = AIS25BA_XL_16kHz;
332 break;
333
334 case AIS25BA_XL_24kHz:
335 val->xl.odr = AIS25BA_XL_24kHz;
336 break;
337
338 case AIS25BA_XL_HW_SEL:
339 val->xl.odr = AIS25BA_XL_HW_SEL;
340 break;
341
342 default:
343 val->xl.odr = AIS25BA_XL_OFF;
344 break;
345 }
346
347 return ret;
348 }
349
350 /**
351 * @brief Read data in engineering unit.[get]
352 *
353 * @param tdm_stream data stream from TDM interface.(ptr)
354 * @param md the TDM interface configuration.(ptr)
355 * @param data data read by the sensor.(ptr)
356 *
357 * @retval interface status (MANDATORY: return 0 -> no Error).
358 *
359 */
ais25ba_data_get(uint16_t * tdm_stream,ais25ba_bus_mode_t * md,ais25ba_data_t * data)360 int32_t ais25ba_data_get(uint16_t *tdm_stream, ais25ba_bus_mode_t *md,
361 ais25ba_data_t *data)
362 {
363 uint8_t offset;
364 uint8_t i;
365
366 if (md->tdm.mapping == PROPERTY_DISABLE)
367 {
368 offset = 0; /* slot0-1-2 */
369 }
370
371 else
372 {
373 offset = 4; /* slot4-5-6 */
374 }
375
376 for (i = 0U; i < 3U; i++)
377 {
378 data->xl.raw[i] = (int16_t) tdm_stream[i + offset];
379 data->xl.mg[i] = ais25ba_from_raw_to_mg(data->xl.raw[i]);
380 }
381
382 return 0;
383 }
384
385 /**
386 * @brief Linear acceleration sensor self-test enable.[set]
387 *
388 * @param ctx read / write interface definitions.(ptr)
389 * @param val enable/ disable selftest
390 *
391 * @retval interface status (MANDATORY: return 0 -> no Error).
392 *
393 */
ais25ba_self_test_set(const stmdev_ctx_t * ctx,uint8_t val)394 int32_t ais25ba_self_test_set(const stmdev_ctx_t *ctx, uint8_t val)
395 {
396 ais25ba_test_reg_t test_reg;
397 int32_t ret;
398
399 ret = ais25ba_read_reg(ctx, AIS25BA_TEST_REG, (uint8_t *)&test_reg, 1);
400
401 if (ret == 0)
402 {
403 test_reg.st = val;
404 ret = ais25ba_write_reg(ctx, AIS25BA_TEST_REG, (uint8_t *)&test_reg, 1);
405 }
406
407 return ret;
408 }
409
410 /**
411 * @brief Linear acceleration sensor self-test enable.[get]
412 *
413 * @param ctx read / write interface definitions.(ptr)
414 * @param val enable/ disable selftest.(ptr)
415 *
416 * @retval interface status (MANDATORY: return 0 -> no Error).
417 *
418 */
ais25ba_self_test_get(const stmdev_ctx_t * ctx,uint8_t * val)419 int32_t ais25ba_self_test_get(const stmdev_ctx_t *ctx, uint8_t *val)
420 {
421 ais25ba_test_reg_t test_reg;
422 int32_t ret;
423
424 ret = ais25ba_read_reg(ctx, AIS25BA_TEST_REG, (uint8_t *)&test_reg, 1);
425 *val = test_reg.st;
426
427 return ret;
428 }
429
430 /**
431 * @}
432 *
433 */
434
435 /**
436 * @}
437 *
438 */
439
440 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
441