Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
lsm303d_spi.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
30#include "std.h"
31
32void lsm303d_spi_init(struct Lsm303d_Spi *lsm, struct spi_periph *spi_p, uint8_t slave_idx,
34{
35 /* set spi_peripheral */
36 lsm->spi_p = spi_p;
37
38 /* set internal target mag/acc*/
39 lsm->target = target;
40
41 /* configure spi transaction */
42 lsm->spi_trans.cpol = SPICpolIdleHigh;
43 lsm->spi_trans.cpha = SPICphaEdge2;
44 lsm->spi_trans.dss = SPIDss8bit;
45 lsm->spi_trans.bitorder = SPIMSBFirst;
46 lsm->spi_trans.cdiv = SPIDiv64;
47
48 lsm->spi_trans.select = SPISelectUnselect;
49 lsm->spi_trans.slave_idx = slave_idx;
50 lsm->spi_trans.output_length = 2;
51 lsm->spi_trans.input_length = 8;
52 // callback currently unused
53 lsm->spi_trans.before_cb = NULL;
54 lsm->spi_trans.after_cb = NULL;
55 lsm->spi_trans.input_buf = &(lsm->rx_buf[0]);
56 lsm->spi_trans.output_buf = &(lsm->tx_buf[0]);
57
58 /* set inital status: Success or Done */
59 lsm->spi_trans.status = SPITransDone;
60
61 /* set default LSM303D config options */
63 lsm->init_status = LSM303D_CONF_UNINIT;
64
65 lsm->initialized = FALSE;
66 lsm->data_available_acc = FALSE;
67 lsm->data_available_mag = FALSE;
68}
69
71{
72 lsm->spi_trans.output_length = 2;
73 lsm->spi_trans.input_length = 0;
74 lsm->tx_buf[0] = reg;
75 lsm->tx_buf[1] = val;
76 spi_submit(lsm->spi_p, &(lsm->spi_trans));
77}
78
81{
82 switch (lsm->init_status) {
84 /* query device id */
85 lsm->spi_trans.output_length = 1;
86 lsm->spi_trans.input_length = 2;
87 /* set read bit then reg address */
88 lsm->tx_buf[0] = (1 << 7 | LSM303D_REG_WHO_AM_I);
89 if (spi_submit(lsm->spi_p, &(lsm->spi_trans))) {
90 if (lsm->rx_buf[1] == LSM303D_REG_WHO_I_AM) {
91 lsm->init_status++;
92 }
93 }
94 break;
97 (lsm->conf.acc_rate & LSM303D_AODR_MASK) |
99 lsm->init_status++;
100 break;
103 lsm->init_status++;
104 break;
107 lsm->init_status++;
108 break;
111 lsm->init_status++;
112 return;
113 break;
116 (lsm->conf.mag_rate & LSM303D_M_ODR_MASK));
117 lsm->init_status++;
118 return;
119 break;
122 (lsm->conf.mag_scale & LSM303D_MFS_MASK));
123 lsm->init_status++;
124 break;
127 lsm->init_status++;
128 break;
130 lsm->initialized = TRUE;
131 lsm->spi_trans.status = SPITransDone;
132 return;
133 break;
134 default:
135 break;
136 }
137}
138
139// Configure
141{
142 if (lsm->init_status == LSM303D_CONF_UNINIT) {
143 lsm->init_status++;
144 if (lsm->spi_trans.status == SPITransSuccess || lsm->spi_trans.status == SPITransDone) {
146 }
147 }
148}
149
150// Normal reading
152{
153 if (lsm->target == LSM303D_TARGET_ACC) {
154 if (!(lsm->initialized) || (lsm->initialized && lsm->spi_trans.status == SPITransDone)) {
155 lsm->spi_trans.output_length = 1;
156 lsm->spi_trans.input_length = 8;
157 /* set read bit and multiple byte bit, then address */
158 lsm->tx_buf[0] = LSM303D_REG_STATUS_A | 1 << 7 | 1 << 6;
159 spi_submit(lsm->spi_p, &(lsm->spi_trans));
160 }
161 } else {
162 if (lsm->initialized && lsm->spi_trans.status == SPITransDone) {
163 lsm->spi_trans.output_length = 1;
164 lsm->spi_trans.input_length = 8;
165 /* set read bit and multiple byte bit, then address */
166 lsm->tx_buf[0] = LSM303D_REG_STATUS_M | 1 << 7 | 1 << 6;
167 spi_submit(lsm->spi_p, &(lsm->spi_trans));
168 }
169 }
170}
171
172#define Int16FromBuf(_buf,_idx) ((int16_t)((_buf[_idx+1]<<8) | _buf[_idx]))
173
174
175
177{
178 if (lsm->initialized) {
179 if (lsm->spi_trans.status == SPITransFailed) {
180 lsm->spi_trans.status = SPITransDone;
181 } else if (lsm->spi_trans.status == SPITransSuccess) {
182 if (lsm->target == LSM303D_TARGET_ACC) {
183 if (!(lsm->rx_buf[1] & LSM303D_ZYXADA)) {
184 lsm->spi_trans.status = SPITransDone;
185 return;
186 }
187 lsm->data_accel.vect.x = Int16FromBuf(lsm->rx_buf, 2);
188 lsm->data_accel.vect.y = Int16FromBuf(lsm->rx_buf, 4);
189 lsm->data_accel.vect.z = Int16FromBuf(lsm->rx_buf, 6);
190 lsm->data_available_acc = TRUE;
191 lsm->spi_trans.status = SPITransDone;
192 } else { //magneto
193 if (!(lsm->rx_buf[1] & LSM303D_ZYXMDA)) {
194 lsm->spi_trans.status = SPITransDone;
195 return;
196 }
197 lsm->data_mag.vect.x = Int16FromBuf(lsm->rx_buf, 2);
198 lsm->data_mag.vect.y = Int16FromBuf(lsm->rx_buf, 4);
199 lsm->data_mag.vect.z = Int16FromBuf(lsm->rx_buf, 6);
200 lsm->data_available_mag = TRUE;
201 lsm->spi_trans.status = SPITransDone;
202 }
203 }
204 } else {
205 if (lsm->init_status != LSM303D_CONF_UNINIT) { // Configuring but not yet initialized
206 if (lsm->spi_trans.status == SPITransSuccess || lsm->spi_trans.status == SPITransDone) {
207 lsm->spi_trans.status = SPITransDone;
209 }
210 if (lsm->spi_trans.status == SPITransFailed) {
211 lsm->init_status--;
212 lsm->spi_trans.status = SPITransDone;
213 lsm303d_spi_send_config(lsm); // Retry config (TODO max retry)
214 }
215 }
216 }
217}
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition spi_arch.c:533
@ SPICphaEdge2
CPHA = 1.
Definition spi.h:75
@ SPITransFailed
Definition spi.h:100
@ SPITransSuccess
Definition spi.h:99
@ SPITransDone
Definition spi.h:101
@ SPICpolIdleHigh
CPOL = 1.
Definition spi.h:84
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition spi.h:63
@ SPIMSBFirst
Definition spi.h:112
@ SPIDiv64
Definition spi.h:125
@ SPIDss8bit
Definition spi.h:90
SPI peripheral structure.
Definition spi.h:174
Lsm303dTarget
Definition lsm303d.h:88
@ LSM303D_TARGET_ACC
Definition lsm303d.h:89
@ LSM303D_CONF_DONE
Definition lsm303d.h:85
@ LSM303D_CONF_CTRL_REG2
Definition lsm303d.h:79
@ LSM303D_CONF_CTRL_REG6
Definition lsm303d.h:83
@ LSM303D_CONF_CTRL_REG1
Definition lsm303d.h:78
@ LSM303D_CONF_CTRL_REG5
Definition lsm303d.h:82
@ LSM303D_CONF_CTRL_REG4
Definition lsm303d.h:81
@ LSM303D_CONF_CTRL_REG3
Definition lsm303d.h:80
@ LSM303D_CONF_UNINIT
Definition lsm303d.h:76
@ LSM303D_CONF_WHO_AM_I
Definition lsm303d.h:77
@ LSM303D_CONF_CTRL_REG7
Definition lsm303d.h:84
static void lsm303d_set_default_config(struct Lsm303dConfig *c)
Definition lsm303d.h:93
#define LSM303D_AZEN
#define LSM303D_AYEN
#define LSM303D_INT2_DRDY_M
#define LSM303D_REG_CTRL7
#define LSM303D_M_ODR_MASK
#define LSM303D_AODR_MASK
#define LSM303D_REG_CTRL4
#define LSM303D_AFS_MASK
#define LSM303D_REG_WHO_AM_I
#define LSM303D_INT1_DRDY_A
#define LSM303D_ZYXADA
#define LSM303D_AHPM_MASK
#define LSM303D_REG_CTRL1
#define LSM303D_REG_WHO_I_AM
LSM303D device identifier in LSM303D_REG_WHO_AM_I.
#define LSM303D_ZYXMDA
#define LSM303D_REG_STATUS_M
#define LSM303D_REG_CTRL3
#define LSM303D_REG_CTRL2
#define LSM303D_REG_CTRL5
#define LSM303D_REG_CTRL6
#define LSM303D_AXEN
#define LSM303D_MFS_MASK
#define LSM303D_REG_STATUS_A
void lsm303d_spi_event(struct Lsm303d_Spi *lsm)
void lsm303d_spi_init(struct Lsm303d_Spi *lsm, struct spi_periph *spi_p, uint8_t slave_idx, enum Lsm303dTarget target)
Definition lsm303d_spi.c:32
static void lsm303d_spi_send_config(struct Lsm303d_Spi *lsm)
Configuration function called once before normal use.
Definition lsm303d_spi.c:80
static void lsm303d_spi_tx_reg(struct Lsm303d_Spi *lsm, uint8_t reg, uint8_t val)
Definition lsm303d_spi.c:70
void lsm303d_spi_start_configure(struct Lsm303d_Spi *lsm)
#define Int16FromBuf(_buf, _idx)
void lsm303d_spi_read(struct Lsm303d_Spi *lsm)
Driver for ST LSM303D 3D accelerometer and magnetometer.
uint16_t foo
Definition main_demo5.c:58
#define TRUE
Definition std.h:4
#define FALSE
Definition std.h:5
struct target_t target
Definition target_pos.c:65
uint16_t val[TCOUPLE_NB]
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.