Statistics
| Branch: | Tag: | Revision:

amiro-lld / drivers / HMC5883L / v1 / alld_HMC5883L.c @ 9466e34d

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

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

    
68
  uint8_t txbuffer = HMC5883L_LLD_REGISTER_IDENTIFICATION_A;
69
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,&txbuffer,1,rxbuffer,num,timeout);
70
}
71

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

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

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

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

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

    
127
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,(uint8_t*)&regaddr,1,data,num,timeout);
128
}
129

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

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

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

    
167
  return hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, status, 1, timeout);
168
}
169

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

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

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

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

    
222
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, lock, 1, timeout);
223
  *lock >>= 1;
224
  return status;
225
}
226

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

    
239
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, rdy, 1, timeout);
240
  *rdy &= 1;
241
  return status;
242
}
243

    
244
/** @} */
245