Statistics
| Branch: | Tag: | Revision:

amiro-lld / source / alld_hmc5883l.c @ e2db16a4

History | View | Annotate | Download (8.681 KB)

1 d6728c5b Thomas Schöpping
/*
2
AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  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 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 General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <alld_hmc5883l.h>
20
21
#if defined(AMIROLLD_CFG_USE_HMC5883L) || defined(__DOXYGEN__)
22
23
#include <string.h>
24
25
/**
26
 * @brief Reads the registers starting from idetification register A.
27
 * @param[in]   hmcd        The HMC5883L driver to use.
28
 * @param[out]  rxbuffer    The data read from the identification registers.
29
 * @param[in]   num         Number of registers to read.
30
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
31
 *
32
 * @return The return status indicates whether the function call was successfull or a timeout occured.
33
 */
34
inline apalExitStatus_t
35
hmc5883l_lld_check(const HMC5883LDriver* const hmcd, uint8_t* const rxbuffer, const uint8_t num, const apalTime_t timeout)
36
{
37
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
38
  apalDbgAssert(rxbuffer != NULL);
39
40
  uint8_t txbuffer = HMC5883L_LLD_REGISTER_IDENTIFICATION_A;
41
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,&txbuffer,1,rxbuffer,num,timeout);
42
}
43
44
/**
45
 * @brief Write data to consecutive registers.
46
 * @param[in]   hmcd        The HMC5883L driver to use.
47
 * @param[in]   regaddr     Address of first register.
48
 * @param[in]   data        Bytes to write to the registers.
49
 * @param[in]   num         Number of registers to write.
50
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
51
 *
52
 * @return The return status indicates whether the function call was successfull or a timeout occured.
53
 */
54
inline apalExitStatus_t
55
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)
56
{
57
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
58
  apalDbgAssert(data != NULL);
59
60
  uint8_t buffer[num+1];
61
  buffer[0] = regaddr;
62
  memcpy(buffer+1, data, num);
63
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,buffer,num+1,NULL,0,timeout);
64
}
65
66
/**
67
 * @brief Write data to one registers.
68
 * @param[in]   hmcd        The HMC5883L driver to use.
69
 * @param[in]   regaddr     Address of the register.
70
 * @param[in]   data        Data to write ti the register.
71
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
72
 *
73
 * @return The return status indicates whether the function call was successfull or a timeout occured.
74
 */
75
inline apalExitStatus_t
76
hmc5883l_lld_set_register(const HMC5883LDriver* const hmcd, const hmc5883l_lld_register_t regaddr, const uint8_t data, const apalTime_t timeout)
77
{
78
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
79
80
  uint8_t buffer[2];
81
  buffer[0] = regaddr;
82
  buffer[1] = data;
83
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,buffer,2,NULL,0,timeout);
84
}
85
86
/**
87
 * @brief Read data from consecutive registers.
88
 * @param[in]   hmcd        The HMC5883L driver to use.
89
 * @param[in]   regaddr     Address of first register.
90
 * @param[out]  data        Bytes to read from the registers.
91
 * @param[in]   num         Number of registers to read.
92
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
93
 *
94
 * @return The return status indicates whether the function call was successfull or a timeout occured.
95
 */
96
inline apalExitStatus_t
97
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)
98
{
99
  apalDbgAssert(hmcd != NULL && hmcd->i2cd != NULL);
100
  apalDbgAssert(data != NULL);
101
102
  return apalI2CMasterTransmit(hmcd->i2cd,HMC5883L_LLD_I2C_ADDR,(uint8_t*)&regaddr,1,data,num,timeout);
103
}
104
105
/**
106
 * @brief Read sensor data.
107
 * @param[in]   hmcd        The HMC5883L driver to use.
108
 * @param[out]  data        Sensor data.
109
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
110
 *
111
 * @return The return status indicates whether the function call was successfull or a timeout occured.
112
 */
113
inline apalExitStatus_t
114
hmc5883l_lld_read_data(const HMC5883LDriver* const hmcd, uint16_t* const data, const apalTime_t timeout)
115
{
116
  apalDbgAssert(data != NULL);
117
118
  uint8_t buffer[6];
119
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_DATA_OUT_X_MSB, buffer, 6, timeout);
120
  data[0] = ((uint16_t)buffer[0] << 8) | buffer[1];
121
  data[1] = ((uint16_t)buffer[2] << 8) | buffer[3];
122
  data[2] = ((uint16_t)buffer[4] << 8) | buffer[5];
123
  for (uint8_t dataIdx = 0; dataIdx < 3; dataIdx++) {
124
    if (data[dataIdx] >> 15) {
125
      data[dataIdx] = -1 * ~(data[dataIdx] - 1);
126
    }
127
  }
128
  return status;
129
}
130
131
/**
132
 * @brief Read the status register.
133
 * @param[in]   hmcd        The HMC5883L driver to use.
134
 * @param[out]  status      Content of status register,
135
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
136
 *
137
 * @return The return status indicates whether the function call was successfull or a timeout occured.
138
 */
139
inline apalExitStatus_t
140
hmc5883l_lld_read_status(const HMC5883LDriver* const hmcd, uint8_t* const status, const apalTime_t timeout)
141
{
142
  apalDbgAssert(status != NULL);
143
144
  return hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, status, 1, timeout);
145
}
146
147
/**
148
 * @brief Read the configuration of the hmc5883l.
149
 * @param[in]   hmcd        The HMC5883L driver to use.
150
 * @param[out]  cfg         Structure representing the current configuration.
151
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
152
 *
153
 * @return The return status indicates whether the function call was successfull or a timeout occured.
154
 */
155
inline apalExitStatus_t
156
hmc5883l_lld_read_config(const HMC5883LDriver* const hmcd, hmc5883l_lld_config_t* const cfg, const apalTime_t timeout)
157
{
158
  apalDbgAssert(cfg != NULL);
159
160
  uint8_t conf[3];
161
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_CONFIG_A, conf, 3, timeout);
162
  cfg->avg = conf[0] & (3 << 5);
163
  cfg->outrate = conf[0] & (7 << 2);
164
  cfg->mbias = conf[0] & 3;
165
  cfg->gain = conf[1] & (7 << 5);
166
  cfg->highspeed = conf[2] >> 7;
167
  cfg->mode = conf[2] & 3;
168
  return status;
169
}
170
171
/**
172
 * @brief Write a configuration to the hmc5883l.
173
 * @param[in]   hmcd        The HMC5883L driver to use.
174
 * @param[in]  cfg         Structure representing the new configuration.
175
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
176
 *
177
 * @return The return status indicates whether the function call was successfull or a timeout occured.
178
 */
179
inline apalExitStatus_t
180
hmc5883l_lld_write_config(const HMC5883LDriver* const hmcd, const hmc5883l_lld_config_t cfg, const apalTime_t timeout)
181
{
182
  uint8_t conf[3];
183
  conf[0] = cfg.avg | cfg.outrate | cfg.mbias;
184
  conf[1] = cfg.gain;
185
  conf[2] = (cfg.highspeed << 7) | cfg.mode;
186
  return hmc5883l_lld_write_register(hmcd, HMC5883L_LLD_REGISTER_CONFIG_A, conf, 3, timeout);
187
}
188
189
/**
190
 * @brief Read the lock bit of the status register.
191
 * @param[in]   hmcd        The HMC5883L driver to use.
192
 * @param[in]   lock        Status of the lock bit.
193
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
194
 *
195
 * @return The return status indicates whether the function call was successfull or a timeout occured.
196
 */
197
inline apalExitStatus_t
198
hmc5883l_lld_read_lock(const HMC5883LDriver* const hmcd, uint8_t* const lock, const apalTime_t timeout)
199
{
200
  apalDbgAssert(lock != NULL);
201
202
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, lock, 1, timeout);
203
  *lock >>= 1;
204
  return status;
205
}
206
207
/**
208
 * @brief Read the rdy bit of the status register.
209
 * @param[in]   hmcd        The HMC5883L driver to use.
210
 * @param[in]   rdy         Status of the rdy bit.
211
 * @param[in]   timeout     Timeout for the function to return (in microseconds).
212
 *
213
 * @return The return status indicates whether the function call was successfull or a timeout occured.
214
 */
215
inline apalExitStatus_t
216
hmc5883l_lld_read_rdy(const HMC5883LDriver* const hmcd, uint8_t* const rdy, const apalTime_t timeout)
217
{
218
  apalDbgAssert(rdy != NULL);
219
220
  apalExitStatus_t status = hmc5883l_lld_read_register(hmcd, HMC5883L_LLD_REGISTER_STATUS, rdy, 1, timeout);
221
  *rdy &= 1;
222
  return status;
223
}
224
225
#endif /* defined(AMIROLLD_CFG_USE_HMC5883L) */