1 /**
2   ******************************************************************************
3   * @file    lis3dsh_reg.c
4   * @author  Sensors Software Solution Team
5   * @brief   LIS3DSH driver file
6   ******************************************************************************
7   * @attention
8   *
9   * <h2><center>&copy; Copyright (c) 2021 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 "lis3dsh_reg.h"
21 
22 /**
23   * @defgroup  LIS3DSH
24   * @brief     This file provides a set of functions needed to drive the
25   *            lis3dsh enhanced inertial module.
26   * @{
27   *
28   */
29 
30 /**
31   * @defgroup  LIS3DSH_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   */
lis3dsh_read_reg(stmdev_ctx_t * ctx,uint8_t reg,uint8_t * data,uint16_t len)49 int32_t __weak lis3dsh_read_reg(stmdev_ctx_t *ctx, uint8_t reg,
50                                 uint8_t *data,
51                                 uint16_t len)
52 {
53   int32_t ret;
54 
55   ret = ctx->read_reg(ctx->handle, reg, data, len);
56 
57   return ret;
58 }
59 
60 /**
61   * @brief  Write generic device register
62   *
63   * @param  ctx   communication interface handler.(ptr)
64   * @param  reg   first register address to write.
65   * @param  data  the buffer contains data to be written.(ptr)
66   * @param  len   number of consecutive register to write.
67   * @retval       interface status (MANDATORY: return 0 -> no Error)
68   *
69   */
lis3dsh_write_reg(stmdev_ctx_t * ctx,uint8_t reg,uint8_t * data,uint16_t len)70 int32_t __weak lis3dsh_write_reg(stmdev_ctx_t *ctx, uint8_t reg,
71                                  uint8_t *data,
72                                  uint16_t len)
73 {
74   int32_t ret;
75 
76   ret = ctx->write_reg(ctx->handle, reg, data, len);
77 
78   return ret;
79 }
80 
81 /**
82   * @}
83   *
84   */
85 
86 /**
87   * @defgroup  LIS3DSH_Private_functions
88   * @brief     Section collect all the utility functions needed by APIs.
89   * @{
90   *
91   */
92 
bytecpy(uint8_t * target,uint8_t * source)93 static void bytecpy(uint8_t *target, uint8_t *source)
94 {
95   if ((target != NULL) && (source != NULL))
96   {
97     *target = *source;
98   }
99 }
100 
101 /**
102   * @}
103   *
104   */
105 
106 /**
107   * @defgroup  LIS3DSH_Sensitivity
108   * @brief     These functions convert raw-data into engineering units.
109   * @{
110   *
111   */
lis3dsh_from_fs2_to_mg(int16_t lsb)112 float_t lis3dsh_from_fs2_to_mg(int16_t lsb)
113 {
114   return ((float_t)lsb) * 0.06f;
115 }
116 
lis3dsh_from_fs4_to_mg(int16_t lsb)117 float_t lis3dsh_from_fs4_to_mg(int16_t lsb)
118 {
119   return ((float_t)lsb) * 0.12f;
120 }
121 
lis3dsh_from_fs6_to_mg(int16_t lsb)122 float_t lis3dsh_from_fs6_to_mg(int16_t lsb)
123 {
124   return ((float_t)lsb) * 0.18f;
125 }
126 
lis3dsh_from_fs8_to_mg(int16_t lsb)127 float_t lis3dsh_from_fs8_to_mg(int16_t lsb)
128 {
129   return ((float_t)lsb) * 0.24f;
130 }
131 
lis3dsh_from_fs16_to_mg(int16_t lsb)132 float_t lis3dsh_from_fs16_to_mg(int16_t lsb)
133 {
134   return ((float_t)lsb) * 0.73f;
135 }
136 
lis3dsh_from_lsb_to_celsius(int8_t lsb)137 float_t lis3dsh_from_lsb_to_celsius(int8_t lsb)
138 {
139   return ((float_t)lsb + 25.0f);
140 }
141 
142 /**
143   * @}
144   *
145   */
146 
147 /**
148   * @defgroup  Basic configuration
149   * @brief     This section groups all the functions concerning
150   *            device basic configuration.
151   * @{
152   *
153   */
154 
155 /**
156   * @brief  Device "Who am I".[get]
157   *
158   * @param  ctx   communication interface handler.(ptr)
159   * @param  val   ID values.(ptr)
160   * @retval       interface status (MANDATORY: return 0 -> no Error)
161   *
162   */
lis3dsh_id_get(stmdev_ctx_t * ctx,lis3dsh_id_t * val)163 int32_t lis3dsh_id_get(stmdev_ctx_t *ctx, lis3dsh_id_t *val)
164 {
165   uint8_t reg[3];
166   int32_t ret;
167 
168   ret = lis3dsh_read_reg(ctx, LIS3DSH_INFO1, reg, 3);
169   val->info1  = reg[0];
170   val->info2  = reg[1];
171   val->whoami = reg[2];
172 
173   return ret;
174 }
175 
176 /**
177   * @brief  Configures the bus operating mode.[set]
178   *
179   * @param  ctx   communication interface handler.(ptr)
180   * @param  val   configures the bus operating mode.(ptr)
181   * @retval       interface status (MANDATORY: return 0 -> no Error)
182   *
183   */
lis3dsh_bus_mode_set(stmdev_ctx_t * ctx,lis3dsh_bus_mode_t * val)184 int32_t lis3dsh_bus_mode_set(stmdev_ctx_t *ctx,
185                              lis3dsh_bus_mode_t *val)
186 {
187   lis3dsh_ctrl_reg5_t ctrl_reg5;
188   int32_t ret;
189 
190   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
191 
192   if (ret == 0)
193   {
194     ctrl_reg5.sim = (uint8_t) * val;
195     ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
196   }
197 
198   return ret;
199 }
200 
201 /**
202   * @brief  Get the bus operating mode.[get]
203   *
204   * @param  ctx   communication interface handler.(ptr)
205   * @param  val   retrieves the bus operating.(ptr)
206   * @retval       interface status (MANDATORY: return 0 -> no Error)
207   *
208   */
lis3dsh_bus_mode_get(stmdev_ctx_t * ctx,lis3dsh_bus_mode_t * val)209 int32_t lis3dsh_bus_mode_get(stmdev_ctx_t *ctx,
210                              lis3dsh_bus_mode_t *val)
211 {
212   lis3dsh_ctrl_reg5_t ctrl_reg5;
213   int32_t ret;
214 
215   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
216 
217   switch (ctrl_reg5.sim)
218   {
219     case LIS3DSH_SEL_BY_HW:
220       *val = LIS3DSH_SEL_BY_HW;
221       break;
222 
223     case LIS3DSH_SPI_3W:
224       *val = LIS3DSH_SPI_3W;
225       break;
226 
227     default:
228       *val = LIS3DSH_SEL_BY_HW;
229       break;
230   }
231 
232   return ret;
233 }
234 
235 /**
236   * @brief  Re-initialize the device.[set]
237   *
238   * @param  ctx   communication interface handler.(ptr)
239   * @param  val   re-initialization mode. Refer to datasheet
240   *                      and application note for more information
241   *                      about differencies between boot and sw_reset
242   *                      procedure.(ptr)
243   * @retval       interface status (MANDATORY: return 0 -> no Error)
244   *
245   */
lis3dsh_init_set(stmdev_ctx_t * ctx,lis3dsh_init_t val)246 int32_t lis3dsh_init_set(stmdev_ctx_t *ctx, lis3dsh_init_t val)
247 {
248   lis3dsh_ctrl_reg3_t ctrl_reg3;
249   lis3dsh_ctrl_reg4_t ctrl_reg4;
250   lis3dsh_ctrl_reg6_t ctrl_reg6;
251   int32_t ret;
252 
253 
254   switch (val)
255   {
256     case LIS3DSH_BOOT:
257       ctrl_reg6.boot = (uint8_t)val & (uint8_t)LIS3DSH_BOOT;
258       ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG3, (uint8_t *)&ctrl_reg3, 1);
259       break;
260 
261     case LIS3DSH_RESET:
262       ctrl_reg3.strt = ((uint8_t)val & (uint8_t)LIS3DSH_RESET) >> 1;
263       ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG6, (uint8_t *)&ctrl_reg6, 1);
264       break;
265 
266     case LIS3DSH_DRV_RDY:
267       ctrl_reg4.xen = PROPERTY_ENABLE;
268       ctrl_reg4.yen = PROPERTY_ENABLE;
269       ctrl_reg4.zen = PROPERTY_ENABLE;
270       ctrl_reg4.bdu = PROPERTY_ENABLE;
271       ctrl_reg6.add_inc = PROPERTY_ENABLE;
272       ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG4, (uint8_t *)&ctrl_reg4, 1);
273 
274       if (ret == 0)
275       {
276         ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG6,
277                                 (uint8_t *)&ctrl_reg6, 1);
278       }
279 
280       break;
281 
282     default:
283       ctrl_reg3.strt = ((uint8_t)val & (uint8_t)LIS3DSH_RESET) >> 1;
284       ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG6, (uint8_t *)&ctrl_reg6, 1);
285       break;
286   }
287 
288   return ret;
289 }
290 
291 /**
292   * @brief  Get the status of the device.[get]
293   *
294   * @param  ctx   communication interface handler.(ptr)
295   * @param  val   the status of the device.(ptr)
296   * @retval       interface status (MANDATORY: return 0 -> no Error)
297   *
298   */
lis3dsh_status_get(stmdev_ctx_t * ctx,lis3dsh_status_var_t * val)299 int32_t lis3dsh_status_get(stmdev_ctx_t *ctx,
300                            lis3dsh_status_var_t *val)
301 {
302   lis3dsh_ctrl_reg3_t ctrl_reg3;
303   lis3dsh_ctrl_reg6_t ctrl_reg6;
304   lis3dsh_stat_t stat;
305   int32_t ret;
306 
307   ret = lis3dsh_read_reg(ctx, LIS3DSH_STAT, (uint8_t *)&stat, 1);
308 
309   if (ret == 0)
310   {
311     ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG3, (uint8_t *)&ctrl_reg3, 1);
312   }
313 
314   if (ret == 0)
315   {
316     ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG6, (uint8_t *)&ctrl_reg6, 1);
317   }
318 
319   val->sw_reset = ctrl_reg3.strt;
320   val->boot     = ctrl_reg6.boot;
321   val->drdy_xl  = stat.drdy;
322   val->ovrn_xl  = stat.dor;
323 
324   return ret;
325 }
326 
327 /**
328   * @brief  Interrupt pins hardware signal configuration.[set]
329   *
330   * @param  ctx   communication interface handler.(ptr)
331   * @param  val   the pins hardware signal settings.(ptr)
332   * @retval       interface status (MANDATORY: return 0 -> no Error)
333   *
334   */
lis3dsh_interrupt_mode_set(stmdev_ctx_t * ctx,lis3dsh_int_mode_t * val)335 int32_t lis3dsh_interrupt_mode_set(stmdev_ctx_t *ctx,
336                                    lis3dsh_int_mode_t *val)
337 {
338   lis3dsh_ctrl_reg3_t ctrl_reg3;
339   int32_t ret;
340 
341   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG3, (uint8_t *)&ctrl_reg3, 1);
342 
343   if (ret == 0)
344   {
345     ctrl_reg3.iel = ~(val->latched);
346     ctrl_reg3.iea = ~(val->active_low);
347     ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG3, (uint8_t *)&ctrl_reg3, 1);
348   }
349 
350   return ret;
351 }
352 
353 /**
354   * @brief  Interrupt pins hardware signal configuration.[get]
355   *
356   * @param  ctx   communication interface handler.(ptr)
357   * @param  val   the pins hardware signal settings.(ptr)
358   * @retval       interface status (MANDATORY: return 0 -> no Error)
359   *
360   */
lis3dsh_interrupt_mode_get(stmdev_ctx_t * ctx,lis3dsh_int_mode_t * val)361 int32_t lis3dsh_interrupt_mode_get(stmdev_ctx_t *ctx,
362                                    lis3dsh_int_mode_t *val)
363 {
364   lis3dsh_ctrl_reg3_t ctrl_reg3;
365   int32_t ret;
366 
367   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG3, (uint8_t *)&ctrl_reg3, 1);
368   val->latched = ~(ctrl_reg3.iel);
369   val->active_low = ~(ctrl_reg3.iea);
370 
371   return ret;
372 }
373 
374 /**
375   * @brief  Route interrupt signals on int1 pin.[set]
376   *
377   * @param  ctx   communication interface handler.(ptr)
378   * @param  val   the signals to route on int1 pin.(ptr)
379   * @retval       interface status (MANDATORY: return 0 -> no Error)
380   *
381   */
lis3dsh_pin_int1_route_set(stmdev_ctx_t * ctx,lis3dsh_pin_int1_route_t * val)382 int32_t lis3dsh_pin_int1_route_set(stmdev_ctx_t *ctx,
383                                    lis3dsh_pin_int1_route_t *val)
384 {
385   lis3dsh_ctrl_reg1_t ctrl_reg1;
386   lis3dsh_ctrl_reg2_t ctrl_reg2;
387   lis3dsh_ctrl_reg3_t ctrl_reg3;
388   lis3dsh_ctrl_reg6_t ctrl_reg6;
389   uint8_t reg[5];
390   int32_t ret;
391 
392   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG1, (uint8_t *)&reg, 5);
393   bytecpy((uint8_t *)&ctrl_reg1, &reg[0]);
394   bytecpy((uint8_t *)&ctrl_reg2, &reg[1]);
395   bytecpy((uint8_t *)&ctrl_reg3, &reg[2]);
396   bytecpy((uint8_t *)&ctrl_reg6, &reg[4]);
397   ctrl_reg1.sm1_pin    = ~(val->fsm1);
398   ctrl_reg2.sm2_pin    = ~(val->fsm2);
399   ctrl_reg3.dr_en      = val->drdy_xl;
400   ctrl_reg6.p1_wtm     = val->fifo_th;
401   ctrl_reg6.p1_empty   = val->fifo_empty;
402   ctrl_reg6.p1_overrun = val->fifo_full;
403 
404   if ((val->fsm1 | val->fsm2 | val->drdy_xl |
405        val->fifo_empty | val->fifo_th |
406        val->fifo_full) == PROPERTY_ENABLE)
407   {
408     ctrl_reg3.int1_en = PROPERTY_ENABLE;
409   }
410 
411   else
412   {
413     ctrl_reg3.int1_en = PROPERTY_DISABLE;
414   }
415 
416   bytecpy(&reg[0], (uint8_t *)&ctrl_reg1);
417   bytecpy(&reg[1], (uint8_t *)&ctrl_reg2);
418   bytecpy(&reg[2], (uint8_t *)&ctrl_reg3);
419   bytecpy(&reg[4], (uint8_t *)&ctrl_reg6);
420 
421   if (ret == 0)
422   {
423     ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG1, (uint8_t *)&reg, 5);
424   }
425 
426   return ret;
427 }
428 
429 /**
430   * @brief  Route interrupt signals on int1 pin.[get]
431   *
432   * @param  ctx   communication interface handler.(ptr)
433   * @param  val   the signals that are routed on int1 pin.(ptr)
434   * @retval       interface status (MANDATORY: return 0 -> no Error)
435   *
436   */
lis3dsh_pin_int1_route_get(stmdev_ctx_t * ctx,lis3dsh_pin_int1_route_t * val)437 int32_t lis3dsh_pin_int1_route_get(stmdev_ctx_t *ctx,
438                                    lis3dsh_pin_int1_route_t *val)
439 {
440   lis3dsh_ctrl_reg1_t ctrl_reg1;
441   lis3dsh_ctrl_reg2_t ctrl_reg2;
442   lis3dsh_ctrl_reg3_t ctrl_reg3;
443   lis3dsh_ctrl_reg6_t ctrl_reg6;
444   uint8_t reg[5];
445   int32_t ret;
446 
447   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG1, (uint8_t *)&reg, 5);
448   bytecpy((uint8_t *)&ctrl_reg1, &reg[0]);
449   bytecpy((uint8_t *)&ctrl_reg2, &reg[1]);
450   bytecpy((uint8_t *)&ctrl_reg3, &reg[2]);
451   bytecpy((uint8_t *)&ctrl_reg6, &reg[4]);
452 
453   if (ctrl_reg3.int1_en == PROPERTY_ENABLE)
454   {
455     val->fsm1       = ~(ctrl_reg1.sm1_pin);
456     val->fsm2       = ~(ctrl_reg2.sm2_pin);
457     val->drdy_xl    = ctrl_reg3.dr_en;
458     val->fifo_th    = ctrl_reg6.p1_wtm;
459     val->fifo_empty = ctrl_reg6.p1_empty;
460     val->fifo_full  = ctrl_reg6.p1_overrun;
461   }
462 
463   else
464   {
465     val->fsm1       = PROPERTY_DISABLE;
466     val->fsm2       = PROPERTY_DISABLE;
467     val->drdy_xl    = PROPERTY_DISABLE;
468     val->fifo_th    = PROPERTY_DISABLE;
469     val->fifo_empty = PROPERTY_DISABLE;
470     val->fifo_full  = PROPERTY_DISABLE;
471   }
472 
473   return ret;
474 }
475 
476 /**
477   * @brief  Route interrupt signals on int2 pin.[set]
478   *
479   * @param  ctx   communication interface handler.(ptr)
480   * @param  val   the signals to route on int2 pin.(ptr)
481   * @retval       interface status (MANDATORY: return 0 -> no Error)
482   *
483   */
lis3dsh_pin_int2_route_set(stmdev_ctx_t * ctx,lis3dsh_pin_int2_route_t * val)484 int32_t lis3dsh_pin_int2_route_set(stmdev_ctx_t *ctx,
485                                    lis3dsh_pin_int2_route_t *val)
486 {
487   lis3dsh_ctrl_reg1_t ctrl_reg1;
488   lis3dsh_ctrl_reg2_t ctrl_reg2;
489   lis3dsh_ctrl_reg3_t ctrl_reg3;
490   lis3dsh_ctrl_reg6_t ctrl_reg6;
491   uint8_t reg[5];
492   int32_t ret;
493 
494   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG1, (uint8_t *)&reg, 5);
495   bytecpy((uint8_t *)&ctrl_reg1, &reg[0]);
496   bytecpy((uint8_t *)&ctrl_reg2, &reg[1]);
497   bytecpy((uint8_t *)&ctrl_reg3, &reg[2]);
498   bytecpy((uint8_t *)&ctrl_reg6, &reg[4]);
499   ctrl_reg1.sm1_pin    = val->fsm1;
500   ctrl_reg2.sm2_pin    = val->fsm2;
501   ctrl_reg6.p2_boot    = val->boot;
502 
503   if ((val->fsm1 | val->fsm2 | val->boot) ==  PROPERTY_ENABLE)
504   {
505     ctrl_reg3.int1_en = PROPERTY_ENABLE;
506   }
507 
508   else
509   {
510     ctrl_reg3.int1_en = PROPERTY_DISABLE;
511   }
512 
513   bytecpy(&reg[0], (uint8_t *)&ctrl_reg1);
514   bytecpy(&reg[1], (uint8_t *)&ctrl_reg2);
515   bytecpy(&reg[2], (uint8_t *)&ctrl_reg3);
516   bytecpy(&reg[4], (uint8_t *)&ctrl_reg6);
517 
518   if (ret == 0)
519   {
520     ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG1, (uint8_t *)&reg, 5);
521   }
522 
523   return ret;
524 }
525 
526 /**
527   * @brief  Route interrupt signals on int2 pin.[get]
528   *
529   * @param  ctx   communication interface handler. Use NULL to ignore
530   *                      this interface.(ptr)
531   * @param  aux_ctx      auxiliary communication interface handler. Use NULL
532   *                      to ignore this interface.(ptr)
533   * @param  val   the signals that are routed on int2 pin.(ptr)
534   * @retval       interface status (MANDATORY: return 0 -> no Error)
535   *
536   */
lis3dsh_pin_int2_route_get(stmdev_ctx_t * ctx,lis3dsh_pin_int2_route_t * val)537 int32_t lis3dsh_pin_int2_route_get(stmdev_ctx_t *ctx,
538                                    lis3dsh_pin_int2_route_t *val)
539 {
540   lis3dsh_ctrl_reg1_t ctrl_reg1;
541   lis3dsh_ctrl_reg2_t ctrl_reg2;
542   lis3dsh_ctrl_reg3_t ctrl_reg3;
543   lis3dsh_ctrl_reg6_t ctrl_reg6;
544   uint8_t reg[5];
545   int32_t ret;
546 
547   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG1, (uint8_t *)&reg, 5);
548   bytecpy((uint8_t *)&ctrl_reg1, &reg[0]);
549   bytecpy((uint8_t *)&ctrl_reg2, &reg[1]);
550   bytecpy((uint8_t *)&ctrl_reg3, &reg[2]);
551   bytecpy((uint8_t *)&ctrl_reg6, &reg[4]);
552 
553   if (ctrl_reg3.int1_en == PROPERTY_ENABLE)
554   {
555     val->fsm1       = ctrl_reg1.sm1_pin;
556     val->fsm2       = ctrl_reg2.sm2_pin;
557     val->boot       = ctrl_reg6.p2_boot;
558   }
559 
560   else
561   {
562     val->fsm1       = PROPERTY_DISABLE;
563     val->fsm2       = PROPERTY_DISABLE;
564     val->boot       = PROPERTY_DISABLE;
565   }
566 
567   return ret;
568 }
569 
570 /**
571   * @brief  Get the status of all the interrupt sources.[get]
572   *
573   * @param  ctx   communication interface handler.(ptr)
574   * @param  val   the status of all the interrupt sources.(ptr)
575   * @retval       interface status (MANDATORY: return 0 -> no Error)
576   *
577   */
lis3dsh_all_sources_get(stmdev_ctx_t * ctx,lis3dsh_all_sources_t * val)578 int32_t lis3dsh_all_sources_get(stmdev_ctx_t *ctx,
579                                 lis3dsh_all_sources_t *val)
580 {
581   lis3dsh_fifo_src_t fifo_src;
582   lis3dsh_stat_t stat;
583   int32_t ret;
584 
585   ret = lis3dsh_read_reg(ctx, LIS3DSH_STAT, (uint8_t *)&stat, 1);
586 
587   if (ret == 0)
588   {
589     ret = lis3dsh_read_reg(ctx, LIS3DSH_FIFO_SRC, (uint8_t *)&fifo_src, 1);
590   }
591 
592   val->drdy_xl        = stat.drdy;
593   val->ovrn_xl        = stat.dor;
594   val->fsm_lc         = stat.l_count;
595   val->fsm_ext_sync   = stat.syncw;
596   val->fsm1_wait_fsm2 = stat.sync1;
597   val->fsm2_wait_fsm1 = stat.sync2;
598   val->fsm1           = stat.int_sm1;
599   val->fsm2           = stat.int_sm2;
600   val->fifo_ovr       = fifo_src.ovrn_fifo;
601   val->fifo_empty     = fifo_src.empty;
602   val->fifo_full      = fifo_src.ovrn_fifo;
603   val->fifo_th        = fifo_src.wtm;
604 
605   return ret;
606 }
607 
608 /**
609   * @brief  Sensor conversion parameters selection.[set]
610   *
611   * @param  ctx   communication interface handler.(ptr)
612   * @param  val   set the sensor conversion parameters by checking
613   *                      the constraints of the device.(ptr)
614   * @retval       interface status (MANDATORY: return 0 -> no Error)
615   *
616   */
lis3dsh_mode_set(stmdev_ctx_t * ctx,lis3dsh_md_t * val)617 int32_t lis3dsh_mode_set(stmdev_ctx_t *ctx, lis3dsh_md_t *val)
618 {
619   lis3dsh_ctrl_reg4_t ctrl_reg4;
620   lis3dsh_ctrl_reg5_t ctrl_reg5;
621   int32_t ret;
622 
623   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG4, (uint8_t *)&ctrl_reg4, 1);
624 
625   if (ret == 0)
626   {
627     ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
628   }
629 
630   ctrl_reg4.odr = (uint8_t)val->odr;
631   ctrl_reg5.fscale = (uint8_t)val->fs;
632 
633   if (ret == 0)
634   {
635     ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG4, (uint8_t *)&ctrl_reg4, 1);
636   }
637 
638   if (ret == 0)
639   {
640     ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
641   }
642 
643   return ret;
644 }
645 
646 /**
647   * @brief  Sensor conversion parameters selection.[get]
648   *
649   * @param  ctx   communication interface handler.(ptr)
650   * @param  val   get the sensor conversion parameters.(ptr)
651   * @retval       interface status (MANDATORY: return 0 -> no Error)
652   *
653   */
lis3dsh_mode_get(stmdev_ctx_t * ctx,lis3dsh_md_t * val)654 int32_t lis3dsh_mode_get(stmdev_ctx_t *ctx, lis3dsh_md_t *val)
655 {
656   lis3dsh_ctrl_reg4_t ctrl_reg4;
657   lis3dsh_ctrl_reg5_t ctrl_reg5;
658   int32_t ret;
659 
660   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG4, (uint8_t *)&ctrl_reg4, 1);
661 
662   if (ret == 0)
663   {
664     ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
665   }
666 
667   switch (ctrl_reg4.odr)
668   {
669     case LIS3DSH_OFF:
670       val->odr = LIS3DSH_OFF;
671       break;
672 
673     case LIS3DSH_3Hz125:
674       val->odr = LIS3DSH_3Hz125;
675       break;
676 
677     case LIS3DSH_6Hz25:
678       val->odr = LIS3DSH_6Hz25;
679       break;
680 
681     case LIS3DSH_12Hz5:
682       val->odr = LIS3DSH_12Hz5;
683       break;
684 
685     case LIS3DSH_25Hz:
686       val->odr = LIS3DSH_25Hz;
687       break;
688 
689     case LIS3DSH_50Hz:
690       val->odr = LIS3DSH_50Hz;
691       break;
692 
693     case LIS3DSH_100Hz:
694       val->odr = LIS3DSH_100Hz;
695       break;
696 
697     case LIS3DSH_400Hz:
698       val->odr = LIS3DSH_400Hz;
699       break;
700 
701     case LIS3DSH_800Hz:
702       val->odr = LIS3DSH_800Hz;
703       break;
704 
705     case LIS3DSH_1kHz6:
706       val->odr = LIS3DSH_1kHz6;
707       break;
708 
709     default:
710       val->odr = LIS3DSH_OFF;
711       break;
712   }
713 
714   switch (ctrl_reg5.fscale)
715   {
716     case LIS3DSH_2g:
717       val->fs = LIS3DSH_2g;
718       break;
719 
720     case LIS3DSH_4g:
721       val->fs = LIS3DSH_4g;
722       break;
723 
724     case LIS3DSH_6g:
725       val->fs = LIS3DSH_6g;
726       break;
727 
728     case LIS3DSH_8g:
729       val->fs = LIS3DSH_8g;
730       break;
731 
732     case LIS3DSH_16g:
733       val->fs = LIS3DSH_16g;
734       break;
735 
736     default:
737       val->fs = LIS3DSH_2g;
738       break;
739   }
740 
741   return ret;
742 }
743 
744 /**
745   * @brief  Read data in engineering unit.[get]
746   *
747   * @param  ctx     communication interface handler.(ptr)
748   * @param  md      the sensor conversion parameters.(ptr)
749   * @retval       interface status (MANDATORY: return 0 -> no Error)
750   *
751   */
lis3dsh_data_get(stmdev_ctx_t * ctx,lis3dsh_md_t * md,lis3dsh_data_t * data)752 int32_t lis3dsh_data_get(stmdev_ctx_t *ctx, lis3dsh_md_t *md,
753                          lis3dsh_data_t *data)
754 {
755   uint8_t buff[6];
756   int32_t ret;
757 
758   uint8_t i;
759   uint8_t j;
760   ret = lis3dsh_read_reg(ctx, LIS3DSH_OUT_T, (uint8_t *)&data->heat.raw, 1);
761 
762   if (ret == 0)
763   {
764     ret = lis3dsh_read_reg(ctx, LIS3DSH_OUT_X_L, (uint8_t *)&buff, 6);
765   }
766 
767   /* temperature conversion */
768   data->heat.deg_c = lis3dsh_from_lsb_to_celsius(data->heat.raw);
769   /* acceleration conversion */
770   j = 0U;
771 
772   for (i = 0U; i < 3U; i++)
773   {
774     data->xl.raw[i] = (int16_t)buff[j + 1U];
775     data->xl.raw[i] = (data->xl.raw[i] * 256) + (int16_t) buff[j];
776     j += 2U;
777 
778     switch (md->fs)
779     {
780       case LIS3DSH_2g:
781         data->xl.mg[i] = lis3dsh_from_fs2_to_mg(data->xl.raw[i]);
782         break;
783 
784       case LIS3DSH_4g:
785         data->xl.mg[i] = lis3dsh_from_fs4_to_mg(data->xl.raw[i]);
786         break;
787 
788       case LIS3DSH_6g:
789         data->xl.mg[i] = lis3dsh_from_fs6_to_mg(data->xl.raw[i]);
790         break;
791 
792       case LIS3DSH_8g:
793         data->xl.mg[i] = lis3dsh_from_fs8_to_mg(data->xl.raw[i]);
794         break;
795 
796       case LIS3DSH_16g:
797         data->xl.mg[i] = lis3dsh_from_fs16_to_mg(data->xl.raw[i]);
798         break;
799 
800       default:
801         data->xl.mg[i] = 0.0f;
802         break;
803     }
804   }
805 
806   return ret;
807 }
808 
809 
810 /**
811   * @}
812   *
813   */
814 
815 /**
816   * @brief  Configures the self test.[set]
817   *
818   * @param  ctx   communication interface handler.(ptr)
819   * @param  val   Self test mode mode.(ptr)
820   * @retval       interface status (MANDATORY: return 0 -> no Error)
821   *
822   */
lis3dsh_self_test_set(stmdev_ctx_t * ctx,lis3dsh_st_t val)823 int32_t lis3dsh_self_test_set(stmdev_ctx_t *ctx, lis3dsh_st_t val)
824 {
825   lis3dsh_ctrl_reg5_t ctrl_reg5;
826   int32_t ret;
827 
828   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
829 
830   if (ret == 0)
831   {
832     ctrl_reg5.st = (uint8_t) val;
833     ret = lis3dsh_write_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
834   }
835 
836   return ret;
837 }
838 
839 /**
840   * @brief  Get self test configuration.[set]
841   *
842   * @param  ctx   communication interface handler.(ptr)
843   * @param  val   Self test mode mode.(ptr)
844   * @retval       interface status (MANDATORY: return 0 -> no Error)
845   *
846   */
lis3dsh_self_test_get(stmdev_ctx_t * ctx,lis3dsh_st_t * val)847 int32_t lis3dsh_self_test_get(stmdev_ctx_t *ctx, lis3dsh_st_t *val)
848 {
849   lis3dsh_ctrl_reg5_t ctrl_reg5;
850   int32_t ret;
851 
852   ret = lis3dsh_read_reg(ctx, LIS3DSH_CTRL_REG5, (uint8_t *)&ctrl_reg5, 1);
853 
854   switch (ctrl_reg5.st)
855   {
856     case LIS3DSH_ST_DISABLE:
857       *val = LIS3DSH_ST_DISABLE;
858       break;
859 
860     case LIS3DSH_ST_POSITIVE:
861       *val = LIS3DSH_ST_POSITIVE;
862       break;
863 
864     case LIS3DSH_ST_NEGATIVE:
865       *val = LIS3DSH_ST_NEGATIVE;
866       break;
867 
868     default:
869       *val = LIS3DSH_ST_DISABLE;
870       break;
871   }
872 
873   return ret;
874 }
875 
876 /**
877   * @}
878   *
879   */
880 
881 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
882