Paparazzi UAS  v6.0_unstable-135-g1952e6d-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 
29 #define RM3100_ADDR_POLL 0x00
30 #define RM3100_ADDR_CMM 0x01
31 #define RM3100_ADDR_CCX 0x04
32 #define RM3100_ADDR_CCY 0x06
33 #define RM3100_ADDR_CCZ 0x08
34 #define RM3100_ADDR_TMRC 0x0B
35 #define RM3100_ADDR_MX 0x24
36 #define RM3100_ADDR_MY 0x27
37 #define RM3100_ADDR_MZ 0x2A
38 #define RM3100_ADDR_BIST 0x33
39 #define RM3100_ADDR_STATUS 0x34
40 #define RM3100_ADDR_HSHAKE 0x35
41 #define RM3100_ADDR_REVID 0x36
42 
43 #define RM3100_CCX_DEFAULT_MSB 0x00
44 #define RM3100_CCX_DEFAULT_LSB 0xC8
45 #define RM3100_CCY_DEFAULT_MSB RM3100_CCX_DEFAULT_MSB
46 #define RM3100_CCY_DEFAULT_LSB RM3100_CCX_DEFAULT_LSB
47 #define RM3100_CCZ_DEFAULT_MSB RM3100_CCX_DEFAULT_MSB
48 #define RM3100_CCZ_DEFAULT_LSB RM3100_CCX_DEFAULT_LSB
49 #define RM3100_CMM_DEFAULT 0x70 // No continuous mode
50 #define RM3100_CONTINUOUS_MODE (1 << 0)
51 #define RM3100_POLLING_MODE (0 << 0)
52 #define RM3100_BIST_SELFTEST 0x8F
53 #define RM3100_BIST_DEFAULT 0x00
54 #define RM3100_BIST_XYZ_OK ((1 << 4) | (1 << 5) | (1 << 6))
55 #define RM3100_STATUS_DRDY (1 << 7)
56 #define RM3100_POLL_XYZ 0x70
57 #define RM3100_RM3100_REVID 0x22
58 
59 void rm3100_init(struct Rm3100 *mag, struct i2c_periph *i2c_p, uint8_t addr, uint8_t data_rate)
60 {
61  /* set i2c_peripheral */
62  mag->i2c_p = i2c_p;
63  /* set i2c address */
64  mag->i2c_trans.slave_addr = addr;
66  /* store data rate */
67  mag->data_rate = data_rate;
68 
69  mag->initialized = false;
71  mag->data_available = false;
72 }
73 
74 // Configure
75 void rm3100_configure(struct Rm3100 *mag)
76 {
77  // Only configure when not busy
79  && mag->i2c_trans.status != I2CTransDone) {
80  return;
81  }
82 
83  // Only when succesfull continue with next
84  if (mag->i2c_trans.status == I2CTransSuccess) {
85  mag->status++;
86  }
87 
89  switch (mag->status) {
90 
91  case RM3100_CONF_UNINIT:
92  /* prepare config request */
93  mag->i2c_trans.buf[0] = RM3100_ADDR_CCX; // start at CCR X reg
100  // send config request
101  i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 7);
102  break;
103 
105  /* prepare config request */
106  mag->i2c_trans.buf[0] = RM3100_ADDR_TMRC; // start at TMRC reg
107  mag->i2c_trans.buf[1] = mag->data_rate;
108  // send config request
109  i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 2);
110  break;
111 
113  /* prepare config request */
114  mag->i2c_trans.buf[0] = RM3100_ADDR_CMM; // start at CMM reg
116  // send config request
117  i2c_transmit(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 2);
118  break;
119 
121  mag->status = RM3100_STATUS_IDLE;
122  mag->initialized = true;
123  break;
124 
125  default:
126  break;
127  }
128 }
129 
130 void rm3100_read(struct Rm3100 *mag)
131 {
132  if (mag->status != RM3100_STATUS_IDLE) {
133  return;
134  }
135 
136  // get 3 x 3bytes data = 9
137  mag->i2c_trans.buf[0] = RM3100_ADDR_MX;
138  i2c_transceive(mag->i2c_p, &(mag->i2c_trans), mag->i2c_trans.slave_addr, 1, 9);
139  mag->status = RM3100_STATUS_MEAS;
140 }
141 
142 // Get raw value
143 // 24 bits signed 2's complement format
144 // return as a signed 32 bits integer
145 static int32_t rm3100_get_raw_from_buf(const volatile uint8_t *buf, uint8_t idx)
146 {
147  uint32_t raw = (uint32_t)((buf[idx] << 16) | (buf[idx+1] << 8) | buf[idx+2]);
148  uint8_t shift = 32 - 24;
149  return (int32_t)(raw << shift) >> shift;
150 }
151 
152 void rm3100_event(struct Rm3100 *mag)
153 {
154  if (!mag->initialized) {
155  return;
156  }
157 
158  switch (mag->status) {
159 
160  case RM3100_STATUS_MEAS:
161  if (mag->i2c_trans.status == I2CTransSuccess) {
162  // Copy the data
163  mag->data.vect.x = rm3100_get_raw_from_buf(mag->i2c_trans.buf, 0);
164  mag->data.vect.y = rm3100_get_raw_from_buf(mag->i2c_trans.buf, 3);
165  mag->data.vect.z = rm3100_get_raw_from_buf(mag->i2c_trans.buf, 6);
166  mag->data_available = true;
167  // End reading, back to idle
168  mag->status = RM3100_STATUS_IDLE;
169  }
170  break;
171 
172  default:
174  // Goto idle
176  mag->status = RM3100_STATUS_IDLE;
177  }
178  break;
179  }
180 }
181 
struct i2c_periph * i2c_p
peripheral used for communcation
Definition: rm3100.h:73
static uint32_t idx
union Rm3100::@338 data
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
transaction successfully finished by I2C driver
Definition: i2c.h:57
#define RM3100_CCY_DEFAULT_LSB
Definition: rm3100.c:46
void rm3100_configure(struct Rm3100 *mag)
Definition: rm3100.c:75
#define RM3100_CCX_DEFAULT_MSB
Definition: rm3100.c:43
#define RM3100_POLL_XYZ
Definition: rm3100.c:56
static int32_t rm3100_get_raw_from_buf(const volatile uint8_t *buf, uint8_t idx)
Definition: rm3100.c:145
#define RM3100_CONTINUOUS_MODE
Definition: rm3100.c:50
void rm3100_event(struct Rm3100 *mag)
Definition: rm3100.c:152
#define RM3100_ADDR_TMRC
Definition: rm3100.c:34
enum Rm3100Status status
init status
Definition: rm3100.h:77
void rm3100_init(struct Rm3100 *mag, struct i2c_periph *i2c_p, uint8_t addr, uint8_t data_rate)
Definition: rm3100.c:59
transaction set to done by user level
Definition: i2c.h:59
#define RM3100_ADDR_CCX
Definition: rm3100.c:31
int int32_t
Typedef defining 32 bit int type.
Definition: vl53l1_types.h:83
void rm3100_read(struct Rm3100 *mag)
Definition: rm3100.c:130
uint8_t data_rate
sensor data rate
Definition: rm3100.h:75
transaction failed
Definition: i2c.h:58
#define RM3100_CCY_DEFAULT_MSB
Definition: rm3100.c:45
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:344
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
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:324
#define RM3100_CCZ_DEFAULT_MSB
Definition: rm3100.c:47
uint8_t slave_addr
Slave address.
Definition: i2c.h:104
bool initialized
config done flag
Definition: rm3100.h:76
volatile bool data_available
data ready flag
Definition: rm3100.h:78
Definition: rm3100.h:72
PNI RM3100 3-axis magnetometer driver interface (I2C).
#define RM3100_ADDR_MX
Definition: rm3100.c:35
#define RM3100_CCX_DEFAULT_LSB
Definition: rm3100.c:44
#define RM3100_CCZ_DEFAULT_LSB
Definition: rm3100.c:48
#define RM3100_ADDR_CMM
Definition: rm3100.c:30
struct i2c_transaction i2c_trans
i2c transaction
Definition: rm3100.h:74
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78