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
lsm303dlhc_i2c.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2011 Gautier Hattenberger <gautier.hattenberger@enac.fr>
3 * 2013 Felix Ruess <felix.ruess@gmail.com>
4 *
5 * This file is part of paparazzi.
6 *
7 * paparazzi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * paparazzi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with paparazzi; see the file COPYING. If not, write to
19 * the Free Software Foundation, 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
31#include "std.h"
32
39void lsm303dlhc_i2c_init(struct Lsm303dlhc_i2c *lsm, struct i2c_periph *i2c_p, uint8_t addr)
40{
41 /* set i2c_peripheral */
42 lsm->i2c_p = i2c_p;
43 /* set i2c address */
44 lsm->i2c_trans.slave_addr = addr;
45 lsm->i2c_trans.status = I2CTransDone;
46 /* set default config options */
47 if (addr == LSM303DLHC_ACC_ADDR) {
49 lsm->init_status.acc = LSM_CONF_ACC_UNINIT;
50 } else {
52 lsm->init_status.mag = LSM_CONF_MAG_UNINIT;
53 }
54 lsm->initialized = false;
55}
56
58{
59 lsm->i2c_trans.type = I2CTransTx;
60 lsm->i2c_trans.buf[0] = reg;
61 lsm->i2c_trans.buf[1] = val;
62 lsm->i2c_trans.len_r = 0;
63 lsm->i2c_trans.len_w = 2;
64 i2c_submit(lsm->i2c_p, &(lsm->i2c_trans));
65}
66
69{
70 if (lsm->i2c_trans.slave_addr == LSM303DLHC_ACC_ADDR) {
71 switch (lsm->init_status.acc) {
74 (lsm->config.acc.scale & LSM303DLHC_FS_MASK) |
75 (lsm->config.acc.hres & LSM303DLHC_DEFAULT_HR));
76 lsm->init_status.acc++;
77 break;
80 (lsm->config.acc.rate & LSM303DLHC_ODR_MASK) |
81 (lsm->config.acc.lp_mode & LSM303DLHC_LPen) |
83 lsm->init_status.acc++;
84 break;
87 lsm->init_status.acc++;
88 break;
90 lsm->initialized = true;
91 lsm->i2c_trans.status = I2CTransDone;
93 break;
94 default:
95 break;
96 }
97 } else {
98 switch (lsm->init_status.mag) {
101 lsm->init_status.mag++;
102 break;
105 lsm->init_status.mag++;
106 break;
109 lsm->init_status.mag++;
110 break;
112 lsm->initialized = true;
113 lsm->i2c_trans.status = I2CTransDone;
114 break;
115 default:
116 break;
117 }
118 }
119}
120
121// Configure
123{
124 if (lsm->i2c_trans.slave_addr == LSM303DLHC_ACC_ADDR) {
125 if (lsm->init_status.acc == LSM_CONF_ACC_UNINIT) {
126 lsm->init_status.acc++;
127 if (lsm->i2c_trans.status == I2CTransSuccess || lsm->i2c_trans.status == I2CTransDone) {
129 }
130 }
131 } else {
132 if (lsm->init_status.mag == LSM_CONF_MAG_UNINIT) {
133 lsm->init_status.mag++;
134 if (lsm->i2c_trans.status == I2CTransSuccess || lsm->i2c_trans.status == I2CTransDone) {
136 }
137 }
138 }
139}
140
141// Normal reading
143{
144 if (lsm->i2c_trans.slave_addr == LSM303DLHC_ACC_ADDR) {
145 //if ((lsm->init_status.acc == LSM_CONF_ACC_CLR_INT_READ) && (lsm->i2c_trans.status == I2CTransDone)){
146 if (!(lsm->initialized) || (lsm->initialized && lsm->i2c_trans.status == I2CTransDone)) {
147 lsm->i2c_trans.buf[0] = LSM303DLHC_REG_OUT_X_L_A | 0x80;
148 lsm->i2c_trans.type = I2CTransTxRx;
149 lsm->i2c_trans.len_r = 6;
150 lsm->i2c_trans.len_w = 1;
151 i2c_submit(lsm->i2c_p, &(lsm->i2c_trans));
152 }
153 } else {
154 if (lsm->initialized && lsm->i2c_trans.status == I2CTransDone) {
155 lsm->i2c_trans.buf[0] = LSM303DLHC_REG_OUT_X_H_M;
156 lsm->i2c_trans.type = I2CTransTxRx;
157 lsm->i2c_trans.len_r = 6;
158 lsm->i2c_trans.len_w = 1;
159 i2c_submit(lsm->i2c_p, &(lsm->i2c_trans));
160 }
161 }
162}
163
164#define Int16FromBuf(_buf,_idx) ((int16_t)((_buf[_idx+1]<<8) | _buf[_idx]))
165
167{
168 if (lsm->initialized) {
169 if (lsm->i2c_trans.status == I2CTransFailed) {
170 lsm->i2c_trans.status = I2CTransDone;
171 } else if (lsm->i2c_trans.status == I2CTransSuccess) {
172 lsm->data.vect.x = Int16FromBuf(lsm->i2c_trans.buf, 0);
173 lsm->data.vect.y = Int16FromBuf(lsm->i2c_trans.buf, 2);
174 lsm->data.vect.z = Int16FromBuf(lsm->i2c_trans.buf, 4);
175 lsm->data_available = true;
176 lsm->i2c_trans.status = I2CTransDone;
177 } else {
178 }
179 } else {
180 if (lsm->i2c_trans.slave_addr == LSM303DLHC_ACC_ADDR) {
181 if (lsm->init_status.acc != LSM_CONF_ACC_UNINIT) { // Configuring but not yet initialized
182 if (lsm->i2c_trans.status == I2CTransSuccess || lsm->i2c_trans.status == I2CTransDone) {
183 lsm->i2c_trans.status = I2CTransDone;
185 }
186 if (lsm->i2c_trans.status == I2CTransFailed) {
187 lsm->init_status.acc--;
188 lsm->i2c_trans.status = I2CTransDone;
189 lsm303dlhc_send_config(lsm); // Retry config (TODO max retry)
190 }
191 }
192 } else {
193 if (lsm->init_status.mag != LSM_CONF_MAG_UNINIT) { // Configuring but not yet initialized
194 if (lsm->i2c_trans.status == I2CTransSuccess || lsm->i2c_trans.status == I2CTransDone) {
195 lsm->i2c_trans.status = I2CTransDone;
197 }
198 if (lsm->i2c_trans.status == I2CTransFailed) {
199 lsm->init_status.mag--;
200 lsm->i2c_trans.status = I2CTransDone;
201 lsm303dlhc_send_config(lsm); // Retry config (TODO max retry)
202 }
203 }
204 }
205 }
206}
enum I2CStatus status
Definition i2c.h:155
static bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
Submit a I2C transaction.
Definition i2c.h:266
@ 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
@ I2CTransTx
transmit only transaction
Definition i2c.h:47
@ I2CTransTxRx
transmit and receive transaction
Definition i2c.h:49
static void lsm303dlhc_mag_set_default_config(struct Lsm303dlhcMagConfig *c)
Definition lsm303dlhc.h:92
static void lsm303dlhc_acc_set_default_config(struct Lsm303dlhcAccConfig *c)
Definition lsm303dlhc.h:86
static void lsm303dlhc_i2c_tx_reg(struct Lsm303dlhc_I2c *lsm, uint8_t reg, uint8_t val)
void lsm303dlhc_i2c_read(struct Lsm303dlhc *lsm)
void lsm303dlhc_i2c_event(struct Lsm303dlhc *lsm)
void lsm303dlhc_i2c_init(struct Lsm303dlhc_i2c *lsm, struct i2c_periph *i2c_p, uint8_t addr)
Initialize Lsm303dlhc struct and set default config options.
static void lsm303dlhc_i2c_send_config(struct Lsm303dlhc_I2c *lsm)
Configuration function called once before normal use.
void lsm303dlhc_i2c_start_configure(struct Lsm303dlhc_I2c *lsm)
#define Int16FromBuf(_buf, _idx)
#define LSM303DLHC_REG_OUT_X_H_M
#define LSM303DLHC_ACC_ADDR
#define LSM303DLHC_Xen
#define LSM303DLHC_FS_MASK
#define LSM303DLHC_Yen
#define LSM303DLHC_Zen
#define LSM303DLHC_REG_OUT_X_L_A
uint16_t foo
Definition main_demo5.c:58
uint16_t val[TCOUPLE_NB]
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.