Statistics
| Branch: | Tag: | Revision:

amiro-lld / source / alld_hmc5883l.c @ 21076167

History | View | Annotate | Download (10.175 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
apalExitStatus_t hmc5883l_lld_check(const HMC5883LDriver* const hmcd, uint8_t* const rxbuffer, const uint8_t num, const apalTime_t timeout)
67
{
68
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
69
  apalDbgAssert(rxbuffer != NULL);
70

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

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

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

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

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

    
115
/**
116
 * @brief Read data from consecutive registers.
117
 * @param[in]   hmcd        The HMC5883L driver to use.
118
 * @param[in]   regaddr     Address of first register.
119
 * @param[out]  data        Bytes to read from the registers.
120
 * @param[in]   num         Number of registers to read.
121
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
122
 *
123
 * @return The return status indicates whether the function call was successfull or a timeout occured.
124
 */
125
apalExitStatus_t 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)
126
{
127
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
128
  apalDbgAssert(data != NULL);
129

    
130
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,(uint8_t*)&regaddr,1,data,num,timeout);
131
}
132

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

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

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

    
170
  return hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, status, 1, timeout);
171
}
172

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

    
185
  uint8_t conf[3];
186
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_CONFIG_A, conf, 3, timeout);
187
  cfg->avg = conf[0] & (3 << 5);
188
  cfg->outrate = conf[0] & (7 << 2);
189
  cfg->mbias = conf[0] & 3;
190
  cfg->gain = conf[1] & (7 << 5);
191
  cfg->highspeed = conf[2] >> 7;
192
  cfg->mode = conf[2] & 3;
193
  return status;
194
}
195

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

    
213
/**
214
 * @brief Read the lock bit of the status register.
215
 * @param[in]   hmcd        The HMC5883L driver to use.
216
 * @param[in]   lock        Status of the lock bit.
217
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
218
 *
219
 * @return The return status indicates whether the function call was successfull or a timeout occured.
220
 */
221
apalExitStatus_t hmc5883l_lld_read_lock(const HMC5883LDriver* const hmcd, uint8_t* const lock, const apalTime_t timeout)
222
{
223
  apalDbgAssert(lock != NULL);
224

    
225
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, lock, 1, timeout);
226
  *lock >>= 1;
227
  return status;
228
}
229

    
230
/**
231
 * @brief Read the rdy bit of the status register.
232
 * @param[in]   hmcd        The HMC5883L driver to use.
233
 * @param[in]   rdy         Status of the rdy bit.
234
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
235
 *
236
 * @return The return status indicates whether the function call was successfull or a timeout occured.
237
 */
238
apalExitStatus_t hmc5883l_lld_read_rdy(const HMC5883LDriver* const hmcd, uint8_t* const rdy, const apalTime_t timeout)
239
{
240
  apalDbgAssert(rdy != NULL);
241

    
242
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, rdy, 1, timeout);
243
  *rdy &= 1;
244
  return status;
245
}
246

    
247
#endif /* defined(AMIROLLD_CFG_USE_HMC5883L) */
248

    
249
/** @} */