Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
qmc5883l.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 Paparazzi Team
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
28
29/* Registers Axis X,Y,Z */
30#define QMC5883L_REG_DATXL 0x00
31#define QMC5883L_REG_DATXM 0x01
32#define QMC5883L_REG_DATYL 0x02
33#define QMC5883L_REG_DATYM 0x03
34#define QMC5883L_REG_DATZL 0x04
35#define QMC5883L_REG_DATZM 0x05
36
37/* Register I2C bus transaction Status */
38#define QMC5883L_REG_STATUS 0x06
39
40/* Registers Temperature, relative thus not so useful ATM, therefore not implemented in reading */
41#define QMC5883L_REG_TEMPM 0x07
42#define QMC5883L_REG_TEMPL 0x08
43
44/* Registers Config */
45#define QMC5883L_REG_CONTROL_1 0x09 /* settings for MODE */
46#define QMC5883L_REG_CONTROL_2 0x0A /* settings for INT_ENB */
47#define QMC5883L_REG_RESET_PERIOD 0x0B
48
49#define QMC5883L_REG_IDC 0x0C /* OEM reserved */
50#define QMC5883L_REG_IDD 0x0D /* OEM reserved */
51
52/* Options for CONTROL_1 */
53#define QMC5883L_MODE_STBY 0x00
54#define QMC5883L_MODE_CONT 0x01
55
56/* Options for scale RaNGe(RNG) Gauss */
57#define QMC5883L_RNG_2G 0x00
58#define QMC5883L_RNG_8G 0x10
59
60/* options for Over-Sample Ratio (OSR) */
61#define QMC5883L_OSR_512 0x00 /* Use 512 if powerusage of chip is not an issue */
62#define QMC5883L_OSR_256 0x40
63#define QMC5883L_OSR_128 0x80
64#define QMC5883L_OSR_64 0xC0
65
66void qmc5883l_init(struct Qmc5883l *mag, struct i2c_periph *i2c_p, uint8_t addr, uint8_t data_rate)
67{
68 /* set i2c_peripheral */
69 mag->i2c_p = i2c_p;
70 /* set i2c address */
71 mag->i2c_trans.slave_addr = addr;
73 /* store data rate */
74 mag->data_rate = data_rate;
75 mag->initialized = false;
77 mag->data_available = false;
78}
79
81{
82 // Only configure when not busy
84 && mag->i2c_trans.status != I2CTransDone) {
85 return;
86 }
87
88 // Only when successful continue with next
89 if (mag->i2c_trans.status == I2CTransSuccess) {
90 mag->status++; //Here the Enum Counter goes to the next one
91 }
92
94 switch (mag->status) {
95
97 /* prepare config request */
99 mag->i2c_trans.buf[0] = 0x01;
100 /* send config request, ask for i2c frame for set/reset period */
101 i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 2);
102 break;
103
106 mag->i2c_trans.buf[1] = (QMC5883L_MODE_CONT|QMC5883L_ODR_200|QMC5883L_RNG_8G|QMC5883L_OSR_512);//todo datarate from settings mag->data_rate;
107 i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 2);
108 break;
109
112 mag->i2c_trans.buf[1] = (QMC5883L_MODE_CONT|QMC5883L_ODR_200|QMC5883L_RNG_8G|QMC5883L_OSR_512);//todo datarate from settings //mag->data_rate;
113 i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 2);
114 break;
115
118 mag->initialized = true;
119 break;
120
121 default:
122 break;
123 }
124}
125
126void qmc5883l_read(struct Qmc5883l *mag)
127{
128 if (mag->status != QMC5883L_STATUS_IDLE) {
129 return;
130 }
131
132 /* get 3 x 2 bytes data = 6 Bytes and one status byte = 7 */
139
140 /* Chip transaction status, not used ATM in case of driver mishap once can considder using it */
142 // Add some code if you experience reading issue
143 // DRDY = ((mag->i2c_trans.buf[6]) >> 0) & 1;
144 // OVL = ((mag->i2c_trans.buf[6]) >> 1) & 1;
145 // DOR = ((uint8_t)(mag->i2c_trans.buf[6]) >> 2) & 1;
146
147 i2c_transceive(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 1, 7);
149}
150/* Convert and align raw values */
151#define Int16FromBuf(_buf,_idx) ((int16_t)(_buf[_idx] | (_buf[_idx+1] << 8)))
152
153
154void qmc5883l_event(struct Qmc5883l *mag)
155{
156 if (!mag->initialized) {
157 return;
158 }
159
160 switch (mag->status) {
161
163 if (mag->i2c_trans.status == I2CTransSuccess) {
164 mag->data.vect.x = Int16FromBuf(mag->i2c_trans.buf, 0);
165 mag->data.vect.y = Int16FromBuf(mag->i2c_trans.buf, 2);
166 mag->data.vect.z = Int16FromBuf(mag->i2c_trans.buf, 4);
167
168 /* only set available if measurements valid: -4096 if ADC under/overflow in sensor
169 The sensor sends out 12 bit wrapped in 16 bit, that sometimes gets corrupded */
170 if (mag->data.vect.x >= 4096 || mag->data.vect.y >= 4096 || mag->data.vect.z >= 4096) {
171 //mag->data.adc_overflow_cnt++;
172 mag->data_available = false;
173 }
174 else {
175 mag->data_available = true;
176 }
177 /* End of measure reading, go back to idle */
179 }
180 break;
181
182 default:
184 /* Per default set to idle */
187 }
188 break;
189 }
190}
191
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition i2c.h:122
enum I2CTransactionStatus status
Transaction status.
Definition i2c.h:126
uint8_t slave_addr
Slave address.
Definition i2c.h:104
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition i2c.c:202
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition i2c.c:222
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition i2c.h:57
@ I2CTransFailed
transaction failed
Definition i2c.h:58
@ I2CTransDone
transaction set to done by user level
Definition i2c.h:59
void qmc5883l_event(struct Qmc5883l *mag)
Definition qmc5883l.c:154
#define QMC5883L_REG_DATZM
Definition qmc5883l.c:35
void qmc5883l_read(struct Qmc5883l *mag)
Definition qmc5883l.c:126
#define QMC5883L_RNG_8G
Definition qmc5883l.c:58
#define QMC5883L_MODE_CONT
Definition qmc5883l.c:54
#define QMC5883L_REG_CONTROL_1
Definition qmc5883l.c:45
#define QMC5883L_REG_STATUS
Definition qmc5883l.c:38
#define QMC5883L_REG_DATZL
Definition qmc5883l.c:34
#define QMC5883L_REG_DATXM
Definition qmc5883l.c:31
#define QMC5883L_REG_DATYM
Definition qmc5883l.c:33
#define QMC5883L_OSR_512
Definition qmc5883l.c:61
#define QMC5883L_REG_DATXL
Definition qmc5883l.c:30
#define QMC5883L_REG_DATYL
Definition qmc5883l.c:32
void qmc5883l_configure(struct Qmc5883l *mag)
Definition qmc5883l.c:80
#define QMC5883L_REG_RESET_PERIOD
Definition qmc5883l.c:47
void qmc5883l_init(struct Qmc5883l *mag, struct i2c_periph *i2c_p, uint8_t addr, uint8_t data_rate)
Definition qmc5883l.c:66
#define Int16FromBuf(_buf, _idx)
Definition qmc5883l.c:151
QST QMC5883L 3-axis magnetometer driver interface (I2C).
volatile bool data_available
data ready flag
Definition qmc5883l.h:66
@ QMC5883L_CONF_CCR_DONE
Definition qmc5883l.h:53
@ QMC5883L_CONF_TMRC_DONE
Definition qmc5883l.h:54
@ QMC5883L_STATUS_MEAS
Definition qmc5883l.h:57
@ QMC5883L_STATUS_IDLE
Definition qmc5883l.h:56
@ QMC5883L_CONF_UNINIT
Definition qmc5883l.h:52
@ QMC5883L_CONF_CCM_DONE
Definition qmc5883l.h:55
struct i2c_periph * i2c_p
peripheral used for communcation
Definition qmc5883l.h:61
enum Qmc5883lStatus status
init status
Definition qmc5883l.h:65
bool initialized
config done flag
Definition qmc5883l.h:64
#define QMC5883L_ODR_200
Definition qmc5883l.h:45
union Qmc5883l::@350 data
struct i2c_transaction i2c_trans
i2c transaction
Definition qmc5883l.h:62
uint8_t data_rate
sensor data rate
Definition qmc5883l.h:63
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.