Statistics
| Branch: | Tag: | Revision:

amiro-lld / source / alld_hmc5883l.c @ ef078306

History | View | Annotate | Download (10.243 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    
21
 * @brief   Compass function implementations.
22
 *
23
 * @addtogroup lld_compass
24
 * @{
25
 */
26

    
27
#include <alld_hmc5883l.h>
28

    
29
#if defined(AMIROLLD_CFG_USE_HMC5883L) || defined(__DOXYGEN__)
30

    
31
#include <string.h>
32

    
33
/******************************************************************************/
34
/* LOCAL DEFINITIONS                                                          */
35
/******************************************************************************/
36

    
37
/******************************************************************************/
38
/* EXPORTED VARIABLES                                                         */
39
/******************************************************************************/
40

    
41
/******************************************************************************/
42
/* LOCAL TYPES                                                                */
43
/******************************************************************************/
44

    
45
/******************************************************************************/
46
/* LOCAL VARIABLES                                                            */
47
/******************************************************************************/
48

    
49
/******************************************************************************/
50
/* LOCAL FUNCTIONS                                                            */
51
/******************************************************************************/
52

    
53
/******************************************************************************/
54
/* EXPORTED FUNCTIONS                                                         */
55
/******************************************************************************/
56

    
57
/**
58
 * @brief Reads the registers starting from idetification register A.
59
 * @param[in]   hmcd        The HMC5883L driver to use.
60
 * @param[out]  rxbuffer    The data read from the identification registers.
61
 * @param[in]   num         Number of registers to read.
62
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
63
 *
64
 * @return The return status indicates whether the function call was successfull or a timeout occured.
65
 */
66
inline apalExitStatus_t
67
hmc5883l_lld_check(const HMC5883LDriver* const hmcd, uint8_t* const rxbuffer, const uint8_t num, const apalTime_t timeout)
68
{
69
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
70
  apalDbgAssert(rxbuffer != NULL);
71

    
72
  uint8_t txbuffer = HMC5883L_LLD_REGISTER_IDENTIFICATION_A;
73
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,&txbuffer,1,rxbuffer,num,timeout);
74
}
75

    
76
/**
77
 * @brief Write data to consecutive registers.
78
 * @param[in]   hmcd        The HMC5883L driver to use.
79
 * @param[in]   regaddr     Address of first register.
80
 * @param[in]   data        Bytes to write to the registers.
81
 * @param[in]   num         Number of registers to write.
82
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
83
 *
84
 * @return The return status indicates whether the function call was successfull or a timeout occured.
85
 */
86
inline apalExitStatus_t
87
hmc5883l_lld_write_register(const HMC5883LDriver* const hmcd, const hmc5883l_lld_register_t regaddr, const uint8_t* const data, const uint8_t num, const apalTime_t timeout)
88
{
89
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
90
  apalDbgAssert(data != NULL);
91

    
92
  uint8_t buffer[num+1];
93
  buffer[0] = regaddr;
94
  memcpy(buffer+1, data, num);
95
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,buffer,num+1,NULL,0,timeout);
96
}
97

    
98
/**
99
 * @brief Write data to one registers.
100
 * @param[in]   hmcd        The HMC5883L driver to use.
101
 * @param[in]   regaddr     Address of the register.
102
 * @param[in]   data        Data to write ti the register.
103
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
104
 *
105
 * @return The return status indicates whether the function call was successfull or a timeout occured.
106
 */
107
inline apalExitStatus_t
108
hmc5883l_lld_set_register(const HMC5883LDriver* const hmcd, const hmc5883l_lld_register_t regaddr, const uint8_t data, const apalTime_t timeout)
109
{
110
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
111

    
112
  uint8_t buffer[2];
113
  buffer[0] = regaddr;
114
  buffer[1] = data;
115
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,buffer,2,NULL,0,timeout);
116
}
117

    
118
/**
119
 * @brief Read data from consecutive registers.
120
 * @param[in]   hmcd        The HMC5883L driver to use.
121
 * @param[in]   regaddr     Address of first register.
122
 * @param[out]  data        Bytes to read from the registers.
123
 * @param[in]   num         Number of registers to read.
124
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
125
 *
126
 * @return The return status indicates whether the function call was successfull or a timeout occured.
127
 */
128
inline apalExitStatus_t
129
hmc5883l_lld_read_register(const HMC5883LDriver* const hmcd, const hmc5883l_lld_register_t regaddr, uint8_t* const data, const uint8_t num, const apalTime_t timeout)
130
{
131
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
132
  apalDbgAssert(data != NULL);
133

    
134
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,(uint8_t*)&regaddr,1,data,num,timeout);
135
}
136

    
137
/**
138
 * @brief Read sensor data.
139
 * @param[in]   hmcd        The HMC5883L driver to use.
140
 * @param[out]  data        Sensor data.
141
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
142
 *
143
 * @return The return status indicates whether the function call was successfull or a timeout occured.
144
 */
145
inline apalExitStatus_t
146
hmc5883l_lld_read_data(const HMC5883LDriver* const hmcd, uint16_t* const data, const apalTime_t timeout)
147
{
148
  apalDbgAssert(data != NULL);
149

    
150
  uint8_t buffer[6];
151
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_DATA_OUT_X_MSB, buffer, 6, timeout);
152
  data[0] = ((uint16_t)buffer[0] << 8) | buffer[1];
153
  data[1] = ((uint16_t)buffer[2] << 8) | buffer[3];
154
  data[2] = ((uint16_t)buffer[4] << 8) | buffer[5];
155
  for (uint8_t dataIdx = 0; dataIdx < 3; dataIdx++) {
156
    if (data[dataIdx] >> 15) {
157
      data[dataIdx] = -1 * ~(data[dataIdx] - 1);
158
    }
159
  }
160
  return status;
161
}
162

    
163
/**
164
 * @brief Read the status register.
165
 * @param[in]   hmcd        The HMC5883L driver to use.
166
 * @param[out]  status      Content of status register,
167
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
168
 *
169
 * @return The return status indicates whether the function call was successfull or a timeout occured.
170
 */
171
inline apalExitStatus_t
172
hmc5883l_lld_read_status(const HMC5883LDriver* const hmcd, uint8_t* const status, const apalTime_t timeout)
173
{
174
  apalDbgAssert(status != NULL);
175

    
176
  return hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, status, 1, timeout);
177
}
178

    
179
/**
180
 * @brief Read the configuration of the hmc5883l.
181
 * @param[in]   hmcd        The HMC5883L driver to use.
182
 * @param[out]  cfg         Structure representing the current configuration.
183
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
184
 *
185
 * @return The return status indicates whether the function call was successfull or a timeout occured.
186
 */
187
inline apalExitStatus_t
188
hmc5883l_lld_read_config(const HMC5883LDriver* const hmcd, hmc5883l_lld_config_t* const cfg, const apalTime_t timeout)
189
{
190
  apalDbgAssert(cfg != NULL);
191

    
192
  uint8_t conf[3];
193
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_CONFIG_A, conf, 3, timeout);
194
  cfg->avg = conf[0] & (3 << 5);
195
  cfg->outrate = conf[0] & (7 << 2);
196
  cfg->mbias = conf[0] & 3;
197
  cfg->gain = conf[1] & (7 << 5);
198
  cfg->highspeed = conf[2] >> 7;
199
  cfg->mode = conf[2] & 3;
200
  return status;
201
}
202

    
203
/**
204
 * @brief Write a configuration to the hmc5883l.
205
 * @param[in]   hmcd        The HMC5883L driver to use.
206
 * @param[in]  cfg         Structure representing the new configuration.
207
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
208
 *
209
 * @return The return status indicates whether the function call was successfull or a timeout occured.
210
 */
211
inline apalExitStatus_t
212
hmc5883l_lld_write_config(const HMC5883LDriver* const hmcd, const hmc5883l_lld_config_t cfg, const apalTime_t timeout)
213
{
214
  uint8_t conf[3];
215
  conf[0] = cfg.avg | cfg.outrate | cfg.mbias;
216
  conf[1] = cfg.gain;
217
  conf[2] = (cfg.highspeed << 7) | cfg.mode;
218
  return hmc5883l_lld_write_register(hmcd, HMC5883L_LLD_REGISTER_CONFIG_A, conf, 3, timeout);
219
}
220

    
221
/**
222
 * @brief Read the lock bit of the status register.
223
 * @param[in]   hmcd        The HMC5883L driver to use.
224
 * @param[in]   lock        Status of the lock bit.
225
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
226
 *
227
 * @return The return status indicates whether the function call was successfull or a timeout occured.
228
 */
229
inline apalExitStatus_t
230
hmc5883l_lld_read_lock(const HMC5883LDriver* const hmcd, uint8_t* const lock, const apalTime_t timeout)
231
{
232
  apalDbgAssert(lock != NULL);
233

    
234
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, lock, 1, timeout);
235
  *lock >>= 1;
236
  return status;
237
}
238

    
239
/**
240
 * @brief Read the rdy bit of the status register.
241
 * @param[in]   hmcd        The HMC5883L driver to use.
242
 * @param[in]   rdy         Status of the rdy bit.
243
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
244
 *
245
 * @return The return status indicates whether the function call was successfull or a timeout occured.
246
 */
247
inline apalExitStatus_t
248
hmc5883l_lld_read_rdy(const HMC5883LDriver* const hmcd, uint8_t* const rdy, const apalTime_t timeout)
249
{
250
  apalDbgAssert(rdy != NULL);
251

    
252
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, rdy, 1, timeout);
253
  *rdy &= 1;
254
  return status;
255
}
256

    
257
#endif /* defined(AMIROLLD_CFG_USE_HMC5883L) */
258

    
259
/** @} */