drv_hmc5883l.c
Go to the documentation of this file.
1 /*
2  drv_hmc5883l.c : Support for HMC5883L Magnetometer
3 
4  Adapted from https://github.com/rosflight/firmware/blob/master/src/hmc5883l.cpp
5 
6  This file is part of BreezySTM32.
7 
8  BreezySTM32 is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  BreezySTM32 is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with BreezySTM32. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #include <breezystm32.h>
24 
25 #include <math.h>
26 
27 
28 #define HMC58X3_ADDR 0x1E
29 #define HMC58X3_CRA 0x00
30 #define HMC58X3_CRB 0x01
31 #define HMC58X3_MODE 0x02
32 #define HMC58X3_DATA 0x03
33 #define HMC58X3_STATUS 0x09
34 #define HMC58X3_ID1 0x0A
35 #define HMC58X3_ID2 0x0B
36 #define HMC58X3_ID3 0x0C
37 
38 #define HMC58X3_CRA_NO_AVG 0x00
39 #define HMC58X3_CRA_AVG_2_MEAS 0x20
40 #define HMC58X3_CRA_AVG_4_MEAS 0x40
41 #define HMC58X3_CRA_AVG_8_MEAS 0x60
42 
43 #define HMC58X3_CRA_DO_0_75 0x00
44 #define HMC58X3_CRA_DO_1_5 0x04
45 #define HMC58X3_CRA_DO_3 0x08
46 #define HMC58X3_CRA_DO_7_5 0x0C
47 #define HMC58X3_CRA_DO_15 0x10
48 #define HMC58X3_CRA_DO_30 0x14
49 #define HMC58X3_CRA_DO_75 0x18
50 
51 #define HMC58X3_CRA_MEAS_MODE_NORMAL 0x00
52 #define HMC58X3_CRA_MEAS_MODE_POS_BIAS 0x01
53 #define HMC58X3_CRA_MEAS_MODE_NEG_BIAS 0x02
54 
55 #define HMC58X3_CRB_GN_1370 0x00
56 #define HMC58X3_CRB_GN_1090 0x20
57 #define HMC58X3_CRB_GN_820 0x40
58 #define HMC58X3_CRB_GN_660 0x60
59 #define HMC58X3_CRB_GN_440 0x80
60 #define HMC58X3_CRB_GN_390 0xA0
61 #define HMC58X3_CRB_GN_330 0xC0
62 #define HMC58X3_CRB_GN_230 0xE0
63 
64 #define HMC58X3_MODE_HS 0x80
65 #define HMC58X3_MODE_CONTINUOUS 0x00
66 #define HMC58X3_MODE_SINGLE 0x01
67 #define HMC58X3_MODE_IDLE 0x02
68 
69 #define HMC58X3_SR_LOCK 0x02
70 #define HMC58X3_SR_RDY 0x01
71 
72 #define HMC58X3_TIMEOUT 30000
73 
74 static uint8_t i2c_buf_[6];
75 static volatile float data_[3];
76 static uint32_t last_update_ms_;
77 static uint32_t next_update_ms_;
78 static bool mag_present_;
79 static uint8_t cmd;
80 
81 static void read_cb(uint8_t result);
82 
84 {
85  mag_present_ = false;
86 
87  // Wait for the chip to power up
88 
91 
92  // Detect Magnetometer
93  cmd = 0;
94  if (i2cWrite(HMC58X3_ADDR, 0xFF, cmd) != true)
95  {
96  mag_present_ = false;
97  return false;
98  }
99  else
100  {
101  bool result = true;
102  // Configure HMC5833L
103  result &= i2cWrite(HMC58X3_ADDR, HMC58X3_CRA, HMC58X3_CRA_DO_75 | HMC58X3_CRA_NO_AVG | HMC58X3_CRA_MEAS_MODE_NORMAL ); // 75 Hz Measurement, no bias, no averaging
104  result &= i2cWrite(HMC58X3_ADDR, HMC58X3_CRB, HMC58X3_CRB_GN_390); // 390 LSB/Gauss
105  result &= i2cWrite(HMC58X3_ADDR, HMC58X3_MODE, HMC58X3_MODE_CONTINUOUS); // Continuous Measurement Mode
106  mag_present_ = true;
107  return result;
108  }
109 }
110 
112 {
113  if (mag_present_ && millis() > last_update_ms_ + 1000)
114  mag_present_ = false;
115  return mag_present_;
116 }
117 
119 {
120  if ( millis() > next_update_ms_)
121  {
123  next_update_ms_ += 10;
124  }
125 }
126 
127 void read_cb(uint8_t result)
128 {
129  if (result != I2C_JOB_ERROR)
130  mag_present_ = true;
132  data_[0] = (float)((int16_t)((i2c_buf_[0] << 8) | i2c_buf_[1]));
133  data_[1] = (float)((int16_t)((i2c_buf_[2] << 8) | i2c_buf_[3]));
134  data_[2] = (float)((int16_t)((i2c_buf_[4] << 8) | i2c_buf_[5]));
135 }
136 
137 
139 {
140  mag_data[0] = data_[0];
141  mag_data[1] = data_[1];
142  mag_data[2] = data_[2];
143 }
144 
bool hmc5883lInit()
Definition: drv_hmc5883l.c:83
volatile uint32_t millis(void)
Definition: system.c:50
static uint8_t cmd
Definition: drv_hmc5883l.c:79
bool hmc5883l_present()
Definition: drv_hmc5883l.c:111
static uint32_t last_update_ms_
Definition: drv_hmc5883l.c:76
#define HMC58X3_CRA_MEAS_MODE_NORMAL
Definition: drv_hmc5883l.c:51
static bool mag_present_
Definition: drv_hmc5883l.c:78
#define HMC58X3_CRA_DO_75
Definition: drv_hmc5883l.c:49
static uint8_t i2c_buf_[6]
Definition: drv_hmc5883l.c:74
#define HMC58X3_CRA_NO_AVG
Definition: drv_hmc5883l.c:38
void hmc5883l_async_read(float *mag_data)
Definition: drv_hmc5883l.c:138
bool i2cWrite(uint8_t addr_, uint8_t reg_, uint8_t data)
Definition: drv_i2c.c:152
#define HMC58X3_CRB
Definition: drv_hmc5883l.c:30
static uint32_t next_update_ms_
Definition: drv_hmc5883l.c:77
#define HMC58X3_DATA
Definition: drv_hmc5883l.c:32
#define HMC58X3_MODE
Definition: drv_hmc5883l.c:31
void i2c_queue_job(i2cJobType_t type, uint8_t addr_, uint8_t reg_, uint8_t *data, uint8_t length, volatile uint8_t *status_, void(*CB)(uint8_t))
Definition: drv_i2c.c:579
#define HMC58X3_CRB_GN_390
Definition: drv_hmc5883l.c:60
static volatile float data_[3]
Definition: drv_hmc5883l.c:75
#define HMC58X3_MODE_CONTINUOUS
Definition: drv_hmc5883l.c:65
int16_t mag_data[3]
Definition: hmc5883l_read.c:28
void hmc5883l_request_async_update()
Definition: drv_hmc5883l.c:118
Definition: drv_i2c.h:31
#define HMC58X3_ADDR
Definition: drv_hmc5883l.c:28
#define NULL
Definition: usbd_def.h:50
static void read_cb(uint8_t result)
Definition: drv_hmc5883l.c:127
#define HMC58X3_CRA
Definition: drv_hmc5883l.c:29


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Thu Oct 24 2019 03:17:18