µracoli Manual  Version foo
hmc5883l.h
1 /* Copyright (c) 2013 - 2014 Axel Wachtler
2  All rights reserved.
3 
4  Redistribution and use in source and binary forms, with or without
5  modification, are permitted provided that the following conditions
6  are met:
7 
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the authors nor the names of its contributors
14  may be used to endorse or promote products derived from this software
15  without specific prior written permission.
16 
17  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  POSSIBILITY OF SUCH DAMAGE. */
28 
29 #ifndef HMC5883L_H
30 #define HMC5883L_H
31 
41 /* === includes ============================================================ */
42 #include "sensor_defs.h"
43 
44 /* === macros ============================================================== */
45 
46 #define HMC5883L_ADDR (0x1E)
47 
48 #define RG_HMC5883L_CONFIG_A (0x00)
49 #define RG_HMC5883L_CONFIG_B (0x01)
50 #define RG_HMC5883L_MODE (0x02)
51 #define RG_HMC5883L_DATA_X (0x03)
52 #define RG_HMC5883L_DATA_Y (0x05)
53 #define RG_HMC5883L_DATA_Z (0x07)
54 #define RG_HMC5883L_STATUS (0x09)
55 #define RG_HMC5883L_IDENT_A (0x0A)
56 #define RG_HMC5883L_IDENT_B (0x0B)
57 #define RG_HMC5883L_IDENT_C (0x0C)
58 
59 #define HMC5883L_GAIN (1090) /* LSB/Gauss, default after reset */
60 
61 
62 /* === types =============================================================== */
63 typedef struct
64 {
66  uint8_t addr; /* I2C address */
67 } hmc5883l_ctx_t;
68 
69 /* === prototypes ========================================================== */
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
73 /* === low level functions ================================================== */
74 
75 /* === high level sensor functions ========================================= */
76 
77 static inline void hmc5883l_trigger(void *pctx, bool one_shot)
78 {
79  uint8_t buf[2] = {RG_HMC5883L_MODE, 0x01}; /* Mode 1: single measurement mode */
80  i2c_master_writeread(((hmc5883l_ctx_t*)pctx)->addr, buf, sizeof(buf)/sizeof(buf[0]), NULL, 0);
81 }
82 
83 static inline uint8_t hmc5883l_get_val(void *pctx, uint8_t *pdata)
84 {
85  const uint8_t nbbytes = 6;
86  uint8_t reg = {RG_HMC5883L_DATA_X};
87  uint8_t buf[nbbytes];
89 
90  i2c_master_writeread(((hmc5883l_ctx_t*)pctx)->addr, &reg, 1, buf, nbbytes);
91 
92  p->type = SENSOR_DATA_MAGNETIC;
93  p->sensor = SENSOR_HMC5883L;
94  p->x = (float)((buf[0] << 8) | buf[1]) / HMC5883L_GAIN;
95  p->y = (float)((buf[2] << 8) | buf[3]) / HMC5883L_GAIN;
96  p->z = (float)((buf[4] << 8) | buf[5]) / HMC5883L_GAIN;
97 
98  return sizeof(sensor_magnetic_t);
99 }
100 
101 static inline uint8_t hmc5883l_get_raw(void *pctx, uint8_t *pdata)
102 {
103  /* not implemented */
104  return 0;
105 }
106 
107 static inline void hmc5883l_sleep(void *pctx)
108 {
109  /* not implemented
110  *
111  * Sensor goes to sleep when measurement is finished (started in single-measurement mode)
112  * Should another mode be implemented in the future, sleep must be implemented explicitely
113  */
114 }
115 
122 static inline uint8_t sensor_create_hmc5883l(void *pdata, bool raw, uint8_t addr)
123 {
124  uint8_t rv = sizeof(hmc5883l_ctx_t);
125  hmc5883l_ctx_t *pcfg;
126 
127  if (pdata != NULL)
128  {
129  /* init generic sensor data */
130  pcfg = (hmc5883l_ctx_t *)pdata;
131  pcfg->g.id = SENSOR_HMC5883L;
132  pcfg->g.f_trigger = hmc5883l_trigger;
133  pcfg->g.f_get_val = raw ? hmc5883l_get_raw : hmc5883l_get_val;
134  pcfg->g.f_sleep = hmc5883l_sleep;
135 
136  pcfg->addr = addr;
137 
138  /* TODO: exec calibration and store in calibration structure */
139  }
140  return rv;
141 }
142 
143 #ifdef __cplusplus
144 } /* extern "C" */
145 #endif
146 
147 #endif /* #ifndef HMC5883L_H */
static uint8_t sensor_create_hmc5883l(void *pdata, bool raw, uint8_t addr)
Definition: hmc5883l.h:122
uint8_t i2c_master_writeread(uint8_t devaddr, uint8_t *writebuf, uint8_t bytestowrite, uint8_t *readbuf, uint8_t bytestoread)