Statistics
| Branch: | Tag: | Revision:

amiro-lld / drivers / LIS331DLH / v1 / alld_LIS331DLH.c @ 9466e34d

History | View | Annotate | Download (10.816 KB)

1
/*
2
AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU Lesser General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU Lesser General Public License for more details.
14

15
You should have received a copy of the GNU Lesser General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
/**
20
 * @file    alld_LIS331DLH.c
21
 * @brief   Accelerometer function implementations.
22
 *
23
 * @addtogroup lld_accel
24
 * @{
25
 */
26

    
27
#include <alld_LIS331DLH.h>
28
#include <string.h>
29

    
30
/******************************************************************************/
31
/* LOCAL DEFINITIONS                                                          */
32
/******************************************************************************/
33

    
34
/******************************************************************************/
35
/* EXPORTED VARIABLES                                                         */
36
/******************************************************************************/
37

    
38
/******************************************************************************/
39
/* LOCAL TYPES                                                                */
40
/******************************************************************************/
41

    
42
/******************************************************************************/
43
/* LOCAL VARIABLES                                                            */
44
/******************************************************************************/
45

    
46
/******************************************************************************/
47
/* LOCAL FUNCTIONS                                                            */
48
/******************************************************************************/
49

    
50
/******************************************************************************/
51
/* EXPORTED FUNCTIONS                                                         */
52
/******************************************************************************/
53

    
54
/**
55
 * @brief Read the content of one or more registers.
56
 * @param[in]   lisd      The LIS331DLH driver to use.
57
 * @param[in]   regaddr   The address of the first register.
58
 * @param[out]  data      The data read from the registers.
59
 * @param[in]   length    Number of registers to read.
60
 *
61
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
62
 */
63
apalExitStatus_t lis331dlh_lld_read_register(const LIS331DLHDriver* const lisd, const lis331dlh_lld_register_t regaddr, uint8_t *data, const uint8_t length)
64
{
65
  apalDbgAssert(lisd != NULL && lisd->spid != NULL);
66
  apalDbgAssert(data != NULL);
67

    
68
  uint8_t buffer[length+1];
69
  buffer[0] = regaddr | LIS331DLH_LLD_SPI_READ | ((length > 1) ? LIS331DLH_LLD_SPI_MULT : 0);
70
  apalExitStatus_t status = apalSPIExchange(lisd->spid, buffer, buffer, length+1);
71
  memcpy(data, buffer+1, length);
72
  return status;
73
}
74

    
75
/**
76
 * @brief Write to one or more registers.
77
 * @param[in]   lisd      The LIS331DLH driver to use.
78
 * @param[in]   regaddr   The address of the first register.
79
 * @param[in]   data      The data to be written to the registers.
80
 * @param[in]   length    Number of registers to write.
81
 *
82
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
83
 */
84
apalExitStatus_t lis331dlh_lld_write_register(const LIS331DLHDriver* const lisd, const lis331dlh_lld_register_t regaddr, const uint8_t *data, const uint8_t length)
85
{
86
  apalDbgAssert(lisd != NULL && lisd->spid != NULL);
87
  apalDbgAssert(data != NULL);
88

    
89
  uint8_t buffer[length+1];
90
  buffer[0] = regaddr | LIS331DLH_LLD_SPI_WRITE | ((length > 1) ? LIS331DLH_LLD_SPI_MULT : 0);
91
  memcpy(buffer+1, data, length);
92
  return apalSPITransmit(lisd->spid, buffer, length+1);
93
}
94

    
95
/**
96
 * @brief Reset the high pass filter
97
 * @param[in]   lisd      The LIS331DLH driver to use.
98
 *
99
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
100
 */
101
apalExitStatus_t lis331dlh_lld_reset_hp_filter(const LIS331DLHDriver* const lisd)
102
{
103
  return lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_HP_FILTER_RESET, NULL, 0);
104
}
105

    
106
/**
107
 * @brief Read the sensor data of all 3 axes.
108
 * @param[in]   lisd      The LIS331DLH driver to use.
109
 * @param[out]  data      The sensor data.
110
 * @param[in]   cfg       The current configuration. Needed to find out if the data is saved as little or big endian.
111
 *
112
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
113
 */
114
apalExitStatus_t lis331dlh_lld_read_all_data(const LIS331DLHDriver* const lisd, int16_t *data, const lis331dlh_lld_cfg_t *cfg)
115
{
116
  apalDbgAssert(data != NULL);
117
  apalDbgAssert(cfg != NULL);
118

    
119
  uint8_t buffer[6];
120
  apalExitStatus_t status = lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_OUT_X_L, buffer, 6);
121
  if (!(cfg->registers.ctrl_reg4 & LIS331DLH_LLD_BLE_BE)) {
122
    data[0] = (int16_t) (buffer[0] | (buffer[1] << 8));
123
    data[1] = (int16_t) (buffer[2] | (buffer[3] << 8));
124
    data[2] = (int16_t) (buffer[4] | (buffer[5] << 8));
125
  } else {
126
    data[0] = (int16_t) (buffer[1] | (buffer[0] << 8));
127
    data[1] = (int16_t) (buffer[3] | (buffer[2] << 8));
128
    data[2] = (int16_t) (buffer[5] | (buffer[4] << 8));
129
  }
130
  return status;
131
}
132

    
133
/**
134
 * @brief Read the sensor data of one axis.
135
 * @param[in]   lisd      The LIS331DLH driver to use.
136
 * @param[out]  data      The sensor data.
137
 * @param[in]   axis      The axis for which the data should be read.
138
 * @param[in]   cfg       The current configuration. Needed to find out if the data is saved as little or big endian.
139
 *
140
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
141
 */
142
apalExitStatus_t lis331dlh_lld_read_data(const LIS331DLHDriver* const lisd, int16_t *data, const lis331dlh_lld_axis_t axis, const lis331dlh_lld_cfg_t *cfg)
143
{
144
  apalDbgAssert(data != NULL);
145
  apalDbgAssert(cfg != NULL);
146

    
147
  apalExitStatus_t status = APAL_STATUS_SUCCESS;
148
  uint8_t buffer[2];
149
  switch (axis) {
150
    case LIS331DLH_LLD_X_AXIS:
151
      status = lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_OUT_X_L, buffer, 2);
152
      break;
153
    case LIS331DLH_LLD_Y_AXIS:
154
      status = lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_OUT_Y_L, buffer, 2);
155
      break;
156
    case LIS331DLH_LLD_Z_AXIS:
157
      status = lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_OUT_Z_L, buffer, 2);
158
      break;
159
    default:
160
      return APAL_STATUS_INVALIDARGUMENTS;
161
  }
162
  // entweder jedes mal endian abfragen oder config mit übergeben
163
  if (!(cfg->registers.ctrl_reg4 & LIS331DLH_LLD_BLE_BE)) {
164
    *data = (int16_t) (buffer[0] | (buffer[1] << 8));
165
  } else {
166
    *data = (int16_t) (buffer[1] | (buffer[0] << 8));
167
  }
168
  return status;
169
}
170

    
171
/**
172
 * @brief Read the current configuration
173
 * @param[in]   lisd      The LIS331DLH driver to use.
174
 * @param[out]  cfg       The current configuration.
175
 *
176
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
177
 */
178
apalExitStatus_t lis331dlh_lld_read_config(const LIS331DLHDriver* const lisd, lis331dlh_lld_cfg_t *cfg)
179
{
180
  apalDbgAssert(cfg != NULL);
181

    
182
  return lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_CTRL_REG1, cfg->data, 5);
183
}
184

    
185
/**
186
 * @brief Write the a configuration
187
 * @param[in]   lisd      The LIS331DLH driver to use.
188
 * @param[in]   cfg       The new configuration.
189
 *
190
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
191
 */
192
apalExitStatus_t lis331dlh_lld_write_config(const LIS331DLHDriver* const lisd, const lis331dlh_lld_cfg_t *cfg)
193
{
194
  apalDbgAssert(cfg != NULL);
195

    
196
  return lis331dlh_lld_write_register(lisd, LIS331DLH_LLD_REGISTER_CTRL_REG1, cfg->data, 5);
197
}
198

    
199
/**
200
 * @brief Read the interrupt configuration of one of the interrupts.
201
 * @param[in]   spid        The SPI driver to use.
202
 * @param[out]  cfg         The current interrupt configuration.
203
 * @param[in]   interrupt   The interrupt for which the configuration should be read.
204
 *
205
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
206
 */
207
apalExitStatus_t lis331dlh_lld_read_int_config(const LIS331DLHDriver* const lisd, lis331dlh_lld_int_cfg_t *cfg, const lis331dlh_lld_int_t interrupt)
208
{
209
  apalDbgAssert(cfg != NULL);
210

    
211
  uint8_t buffer[2];
212
  apalExitStatus_t status = APAL_STATUS_OK;
213
  if (interrupt == LIS331DLH_LLD_INT1) {
214
    status |= lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_INT1_CFG, &cfg->cfg_reg, 1);
215
    status |= lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_INT1_THS, buffer, 2);
216
  } else {
217
    status |= lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_INT2_CFG, &cfg->cfg_reg, 1);
218
    status |= lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_INT2_THS, buffer, 2);
219
  }
220
  if (status != APAL_STATUS_OK) {
221
    return status;
222
  }
223
  cfg->threshold = buffer[0];
224
  cfg->duration = buffer[1];
225
  return status;
226
}
227

    
228
/**
229
 * @brief Write the interrupt configuration of one of the interrupts.
230
 * @param[in]   spid        The SPI driver to use.
231
 * @param[in]   cfg         The current new configuration.
232
 * @param[in]   interrupt   The interrupt for which the configuration should be written.
233
 *
234
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
235
 */
236
apalExitStatus_t lis331dlh_lld_write_int_config(const LIS331DLHDriver* const lisd, const lis331dlh_lld_int_cfg_t *cfg, const lis331dlh_lld_int_t interrupt)
237
{
238
  apalDbgAssert(cfg != NULL);
239

    
240
  uint8_t buffer[2];
241
  buffer[0] = cfg->threshold;
242
  buffer[1] = cfg->duration;
243
  apalExitStatus_t status = APAL_STATUS_OK;
244
  if (interrupt == LIS331DLH_LLD_INT1) {
245
    status |= lis331dlh_lld_write_register(lisd, LIS331DLH_LLD_REGISTER_INT1_CFG, &(cfg->cfg_reg), 1);
246
    status |= lis331dlh_lld_write_register(lisd, LIS331DLH_LLD_REGISTER_INT1_THS, buffer, 2);
247
  } else {
248
    status |= lis331dlh_lld_write_register(lisd, LIS331DLH_LLD_REGISTER_INT2_CFG, &(cfg->cfg_reg), 1);
249
    status |= lis331dlh_lld_write_register(lisd, LIS331DLH_LLD_REGISTER_INT2_THS, buffer, 2);
250
  }
251
  return status;
252
}
253

    
254
/**
255
 * @brief Read the status register.
256
 * @param[in]   spid        The SPI driver to use.
257
 * @param[out]  status      The status register value.
258
 *
259
 * @return  The return status indicates whether the function call was succesfull or a timeout occurred.
260
 */
261
apalExitStatus_t lis331dlh_lld_read_status_register(const LIS331DLHDriver* const lisd, uint8_t *status)
262
{
263
  apalDbgAssert(status != NULL);
264

    
265
  return lis331dlh_lld_read_register(lisd, LIS331DLH_LLD_REGISTER_STATUS_REG, status, 1);
266
}
267

    
268
/** @} */
269