Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
rm3100.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021 Gautier Hattenberger <gautier.hattenberger@enac.fr>
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
27#include "peripherals/rm3100.h"
28#if RM3100_USE_MEDIAN_FILTER
30#endif
31
32#define RM3100_ADDR_POLL 0x00
33#define RM3100_ADDR_CMM 0x01
34#define RM3100_ADDR_CCX 0x04
35#define RM3100_ADDR_CCY 0x06
36#define RM3100_ADDR_CCZ 0x08
37#define RM3100_ADDR_TMRC 0x0B
38#define RM3100_ADDR_MX 0x24
39#define RM3100_ADDR_MY 0x27
40#define RM3100_ADDR_MZ 0x2A
41#define RM3100_ADDR_BIST 0x33
42#define RM3100_ADDR_STATUS 0x34
43#define RM3100_ADDR_HSHAKE 0x35
44#define RM3100_ADDR_REVID 0x36
45
46#define RM3100_CCX_DEFAULT_MSB 0x00
47#define RM3100_CCX_DEFAULT_LSB 0xC8
48#define RM3100_CCY_DEFAULT_MSB RM3100_CCX_DEFAULT_MSB
49#define RM3100_CCY_DEFAULT_LSB RM3100_CCX_DEFAULT_LSB
50#define RM3100_CCZ_DEFAULT_MSB RM3100_CCX_DEFAULT_MSB
51#define RM3100_CCZ_DEFAULT_LSB RM3100_CCX_DEFAULT_LSB
52#define RM3100_CMM_DEFAULT 0x70 // No continuous mode
53#define RM3100_CONTINUOUS_MODE (1 << 0)
54#define RM3100_POLLING_MODE (0 << 0)
55#define RM3100_BIST_SELFTEST 0x8F
56#define RM3100_BIST_DEFAULT 0x00
57#define RM3100_BIST_XYZ_OK ((1 << 4) | (1 << 5) | (1 << 6))
58#define RM3100_STATUS_DRDY (1 << 7)
59#define RM3100_POLL_XYZ 0x70
60#define RM3100_RM3100_REVID 0x22
61
62#if RM3100_USE_MEDIAN_FILTER
64#endif
65
66void rm3100_init(struct Rm3100 *mag, struct i2c_periph *i2c_p, uint8_t addr, uint8_t data_rate)
67{
68
69#if RM3100_USE_MEDIAN_FILTER
71#endif
72
73 /* set i2c_peripheral */
74 mag->i2c_p = i2c_p;
75 /* set i2c address */
76 mag->i2c_trans.slave_addr = addr;
78 /* store data rate */
79 mag->data_rate = data_rate;
80
81 mag->initialized = false;
83 mag->data_available = false;
84}
85
86// Configure
87void rm3100_configure(struct Rm3100 *mag)
88{
89 // Only configure when not busy
91 && mag->i2c_trans.status != I2CTransDone) {
92 return;
93 }
94
95 // Only when successful continue with next
96 if (mag->i2c_trans.status == I2CTransSuccess) {
97 mag->status++;
98 }
99
101 switch (mag->status) {
102
104 /* prepare config request */
105 mag->i2c_trans.buf[0] = RM3100_ADDR_CCX; // start at CCR X reg
112 // send config request
113 i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 7);
114 break;
115
117 /* prepare config request */
118 mag->i2c_trans.buf[0] = RM3100_ADDR_TMRC; // start at TMRC reg
119 mag->i2c_trans.buf[1] = mag->data_rate;
120 // send config request
121 i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 2);
122 break;
123
125 /* prepare config request */
126 mag->i2c_trans.buf[0] = RM3100_ADDR_CMM; // start at CMM reg
128 // send config request
129 i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 2);
130 break;
131
134 mag->initialized = true;
135 break;
136
137 default:
138 break;
139 }
140}
141
142void rm3100_read(struct Rm3100 *mag)
143{
144 if (mag->status != RM3100_STATUS_IDLE) {
145 return;
146 }
147
148 // get 3 x 3bytes data = 9
149 mag->i2c_trans.buf[0] = RM3100_ADDR_MX;
150 i2c_transceive(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 1, 9);
152}
153
154// Get raw value
155// 24 bits signed 2's complement format
156// return as a signed 32 bits integer
158{
159 uint32_t raw = (uint32_t)((buf[idx] << 16) | (buf[idx+1] << 8) | buf[idx+2]);
160 uint8_t shift = 32 - 24;
161 return (int32_t)(raw << shift) >> shift;
162}
163
164void rm3100_event(struct Rm3100 *mag)
165{
166 if (!mag->initialized) {
167 return;
168 }
169
170 // If we have a successful reading copy the data
172 // Copy the new data
173 mag->data.vect.x = rm3100_get_raw_from_buf(mag->i2c_trans.buf, 0);
174 mag->data.vect.y = rm3100_get_raw_from_buf(mag->i2c_trans.buf, 3);
175 mag->data.vect.z = rm3100_get_raw_from_buf(mag->i2c_trans.buf, 6);
176
177 // Sometimes, very sporadic, the raw sensordata output gives wrong spikes in measurements for unknown reasons (Hardware, ASIC bug?)
178 // This will cause the AHRS to go wild, therefore the need to get rid of those huge spikes.
179 // A median filter can be enabled to remove the spikes. State will be much better than allowing a huge spiky value.
180 #if RM3100_USE_MEDIAN_FILTER
182 #endif
183 mag->data_available = true;
184 }
185
186 // Always go back to idle
188 // Goto idle
191 }
192}
193
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition i2c.h:123
enum I2CTransactionStatus status
Transaction status.
Definition i2c.h:127
uint8_t slave_addr
Slave address.
Definition i2c.h:105
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:58
@ I2CTransFailed
transaction failed
Definition i2c.h:59
@ I2CTransDone
transaction set to done by user level
Definition i2c.h:60
uint16_t foo
Definition main_demo5.c:58
#define UpdateMedianFilterVect3Int(_f, _v)
#define InitMedianFilterVect3Int(_f, _n)
static uint32_t idx
#define RM3100_CCX_DEFAULT_LSB
Definition rm3100.c:47
void rm3100_init(struct Rm3100 *mag, struct i2c_periph *i2c_p, uint8_t addr, uint8_t data_rate)
Definition rm3100.c:66
#define RM3100_CCZ_DEFAULT_LSB
Definition rm3100.c:51
#define RM3100_ADDR_CCX
Definition rm3100.c:34
#define RM3100_POLL_XYZ
Definition rm3100.c:59
#define RM3100_CCY_DEFAULT_LSB
Definition rm3100.c:49
#define RM3100_ADDR_CMM
Definition rm3100.c:33
#define RM3100_ADDR_MX
Definition rm3100.c:38
#define RM3100_CONTINUOUS_MODE
Definition rm3100.c:53
#define RM3100_CCX_DEFAULT_MSB
Definition rm3100.c:46
#define RM3100_CCY_DEFAULT_MSB
Definition rm3100.c:48
#define RM3100_CCZ_DEFAULT_MSB
Definition rm3100.c:50
void rm3100_read(struct Rm3100 *mag)
Definition rm3100.c:142
void rm3100_configure(struct Rm3100 *mag)
Definition rm3100.c:87
#define RM3100_ADDR_TMRC
Definition rm3100.c:37
void rm3100_event(struct Rm3100 *mag)
Definition rm3100.c:164
static int32_t rm3100_get_raw_from_buf(const volatile uint8_t *buf, uint8_t idx)
Definition rm3100.c:157
PNI RM3100 3-axis magnetometer driver interface (I2C).
@ RM3100_CONF_CCR_DONE
Definition rm3100.h:64
@ RM3100_STATUS_MEAS
Definition rm3100.h:68
@ RM3100_CONF_TMRC_DONE
Definition rm3100.h:65
@ RM3100_STATUS_IDLE
Definition rm3100.h:67
@ RM3100_CONF_UNINIT
Definition rm3100.h:63
@ RM3100_CONF_CCM_DONE
Definition rm3100.h:66
enum Rm3100Status status
init status
Definition rm3100.h:77
bool initialized
config done flag
Definition rm3100.h:76
struct i2c_transaction i2c_trans
i2c transaction
Definition rm3100.h:74
struct i2c_periph * i2c_p
peripheral used for communcation
Definition rm3100.h:73
volatile bool data_available
data ready flag
Definition rm3100.h:78
union Rm3100::@351 data
uint8_t data_rate
sensor data rate
Definition rm3100.h:75
int int32_t
Typedef defining 32 bit int type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.