Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
mpu9250_spi.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013 Gautier Hattenberger
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, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
30
31void mpu9250_spi_init(struct Mpu9250_Spi *mpu, struct spi_periph *spi_p, uint8_t slave_idx)
32{
33 /* set spi_peripheral */
34 mpu->spi_p = spi_p;
35
36 /* configure spi transaction */
41 mpu->spi_trans.cdiv = SPIDiv64;
42
44 mpu->spi_trans.slave_idx = slave_idx;
45 mpu->spi_trans.output_length = 2;
48 mpu->spi_trans.after_cb = NULL;
49 mpu->spi_trans.input_buf = &(mpu->rx_buf[0]);
50 mpu->spi_trans.output_buf = &(mpu->tx_buf[0]);
51
52 /* set inital status: Success or Done */
54
55 /* set default MPU9250 config options */
57
58 mpu->data_available = false;
59 mpu->config.initialized = false;
61
63}
64
65
67{
68 struct Mpu9250_Spi *mpu_spi = (struct Mpu9250_Spi *)(mpu);
70 mpu_spi->spi_trans.input_length = 0;
71 mpu_spi->tx_buf[0] = _reg;
72 mpu_spi->tx_buf[1] = _val;
73 spi_submit(mpu_spi->spi_p, &(mpu_spi->spi_trans));
74}
75
76// Configuration function called once before normal use
78{
80 // First check if we found the chip (succesfull WHO_AM_I response)
82 mpu->config.init_status++;
84 mpu9250_send_config(mpu9250_spi_write_to_reg, (void *)mpu, &(mpu->config));
85 }
86 // Send WHO_AM_I to check if chip is there
87 else if (mpu->spi_trans.status != SPITransRunning && mpu->spi_trans.status != SPITransPending) {
88 mpu->spi_trans.output_length = 1;
89 mpu->spi_trans.input_length = 2;
91 spi_submit(mpu->spi_p, &(mpu->spi_trans));
92 }
93 }
94}
95
97{
98 if (mpu->config.initialized && mpu->spi_trans.status == SPITransDone) {
99 mpu->spi_trans.output_length = 1;
100 mpu->spi_trans.input_length = 1 + mpu->config.nb_bytes;
101 /* set read bit and multiple byte bit, then address */
103 spi_submit(mpu->spi_p, &(mpu->spi_trans));
104 }
105}
106
107#define Int16FromBuf(_buf,_idx) ((int16_t)((_buf[_idx]<<8) | _buf[_idx+1]))
108
110{
111 if (mpu->config.initialized) {
112 if (mpu->spi_trans.status == SPITransFailed) {
114 } else if (mpu->spi_trans.status == SPITransSuccess) {
115 // Successfull reading
116 if (bit_is_set(mpu->rx_buf[1], 0)) {
117 // new data
118 mpu->data_accel.vect.x = Int16FromBuf(mpu->rx_buf, 2);
119 mpu->data_accel.vect.y = Int16FromBuf(mpu->rx_buf, 4);
120 mpu->data_accel.vect.z = Int16FromBuf(mpu->rx_buf, 6);
121 mpu->data_rates.rates.p = Int16FromBuf(mpu->rx_buf, 10);
122 mpu->data_rates.rates.q = Int16FromBuf(mpu->rx_buf, 12);
123 mpu->data_rates.rates.r = Int16FromBuf(mpu->rx_buf, 14);
124
125 // if we are reading slaves, copy the ext_sens_data
126 if (mpu->config.nb_slaves > 0) {
127 /* the buffer is volatile, since filled from ISR
128 * but we know it's ok to use it here so we silence the warning
129 */
130#pragma GCC diagnostic push
131#pragma GCC diagnostic ignored "-Wcast-qual"
132 memcpy(mpu->data_ext, (uint8_t *) & (mpu->rx_buf[16]), mpu->config.nb_bytes - 15);
133#pragma GCC diagnostic pop
134 }
135
136 mpu->data_available = true;
137 }
139 }
140 } else if (mpu->config.init_status != MPU9250_CONF_UNINIT) { // Configuring but not yet initialized
141 switch (mpu->spi_trans.status) {
142 case SPITransFailed:
143 mpu->config.init_status--; // Retry config (TODO max retry)
144 /* Falls through. */
145 case SPITransSuccess:
146 case SPITransDone:
147 mpu9250_send_config(mpu9250_spi_write_to_reg, (void *)mpu, &(mpu->config));
148 if (mpu->config.initialized) {
149 mpu->spi_trans.status = SPITransDone;
150 }
151 break;
152 default:
153 break;
154 }
155 }
156}
157
160{
161 struct Mpu9250_Spi *mpu_spi = (struct Mpu9250_Spi *)(mpu);
162
163 if (mpu_spi->slave_init_status == MPU9250_SPI_CONF_UNINIT) {
165 }
166
167 switch (mpu_spi->slave_init_status) {
169 /* configure MPU I2C master clock and stop/start between slave reads */
170 mpu_set(mpu, MPU9250_REG_I2C_MST_CTRL, ((1 << 4) | mpu_spi->config.i2c_mst_clk));
171 mpu_spi->slave_init_status++;
172 break;
174 /* Set I2C slaves delayed sample rate */
175 mpu_set(mpu, MPU9250_REG_I2C_MST_DELAY, mpu_spi->config.i2c_mst_delay);
176 mpu_spi->slave_init_status++;
177 break;
179 /* enable internal I2C master and disable primary I2C interface */
181 (1 << MPU9250_I2C_MST_EN)));
182 mpu_spi->slave_init_status++;
183 break;
185 /* configure each slave until all nb_slaves are done */
186 if (mpu_spi->config.nb_slave_init < mpu_spi->config.nb_slaves && mpu_spi->config.nb_slave_init < MPU9250_I2C_NB_SLAVES) {
187 // proceed to next slave if configure for current one returns true
188 if (mpu_spi->config.slaves[mpu_spi->config.nb_slave_init].configure(mpu_set, mpu)) {
189 mpu_spi->config.nb_slave_init++;
190 }
191 }
192 else {
193 /* all slave devies configured, continue MPU side configuration of I2C slave stuff */
194 mpu_spi->slave_init_status++;
195 }
196 break;
198 return true;
199 default:
200 break;
201 }
202 return false;
203}
enum SPIClockPolarity cpol
clock polarity control
Definition spi.h:155
enum SPIClockPhase cpha
clock phase control
Definition spi.h:156
enum SPISlaveSelect select
slave selection behavior
Definition spi.h:154
SPICallback before_cb
NULL or function called before the transaction.
Definition spi.h:160
SPICallback after_cb
NULL or function called after the transaction.
Definition spi.h:161
enum SPIDataSizeSelect dss
data transfer word size
Definition spi.h:157
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition spi.h:150
uint16_t input_length
number of data words to read
Definition spi.h:151
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition spi.h:159
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition spi.h:149
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition spi.h:153
enum SPIBitOrder bitorder
MSB/LSB order.
Definition spi.h:158
uint16_t output_length
number of data words to write
Definition spi.h:152
enum SPITransactionStatus status
Definition spi.h:162
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
@ SPITransRunning
Definition spi.h:98
@ SPITransPending
Definition spi.h:97
@ 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
uint16_t foo
Definition main_demo5.c:58
void mpu9250_send_config(Mpu9250ConfigSet mpu_set, void *mpu, struct Mpu9250Config *config)
Configuration sequence called once before normal use.
Definition mpu9250.c:89
void mpu9250_set_default_config(struct Mpu9250Config *c)
Definition mpu9250.c:68
void(* Mpu9250ConfigSet)(void *mpu, uint8_t _reg, uint8_t _val)
Configuration function prototype.
Definition mpu9250.h:118
uint8_t nb_slaves
number of used I2C slaves
Definition mpu9250.h:144
uint8_t nb_bytes
number of bytes to read starting with MPU9250_REG_INT_STATUS
Definition mpu9250.h:135
#define MPU9250_I2C_NB_SLAVES
Definition mpu9250.h:53
enum Mpu9250ConfStatus init_status
init status
Definition mpu9250.h:136
@ MPU9250_CONF_UNINIT
Definition mpu9250.h:103
bool initialized
config done flag
Definition mpu9250.h:137
#define MPU9250_WHOAMI_REPLY
#define MPU9250_REG_WHO_AM_I
#define MPU9250_REG_I2C_MST_DELAY
#define MPU9250_REG_I2C_MST_CTRL
#define MPU9250_SPI_READ
#define MPU9250_I2C_MST_EN
#define MPU9250_REG_USER_CTRL
#define MPU9250_I2C_IF_DIS
#define MPU9250_REG_INT_STATUS
void mpu9250_spi_init(struct Mpu9250_Spi *mpu, struct spi_periph *spi_p, uint8_t slave_idx)
Definition mpu9250_spi.c:31
void mpu9250_spi_read(struct Mpu9250_Spi *mpu)
Definition mpu9250_spi.c:96
static void mpu9250_spi_write_to_reg(void *mpu, uint8_t _reg, uint8_t _val)
Definition mpu9250_spi.c:66
void mpu9250_spi_start_configure(struct Mpu9250_Spi *mpu)
Definition mpu9250_spi.c:77
bool mpu9250_configure_i2c_slaves(Mpu9250ConfigSet mpu_set, void *mpu)
configure the registered I2C slaves
#define Int16FromBuf(_buf, _idx)
void mpu9250_spi_event(struct Mpu9250_Spi *mpu)
Driver for the MPU-9250 using SPI.
volatile bool data_available
data ready flag
Definition mpu9250_spi.h:56
uint8_t data_ext[MPU9250_BUFFER_EXT_LEN]
Definition mpu9250_spi.h:65
enum Mpu9250SpiSlaveInitStatus slave_init_status
Definition mpu9250_spi.h:67
volatile uint8_t rx_buf[MPU9250_BUFFER_LEN]
Definition mpu9250_spi.h:55
struct Mpu9250Config config
Definition mpu9250_spi.h:66
volatile uint8_t tx_buf[2]
Definition mpu9250_spi.h:54
struct spi_periph * spi_p
Definition mpu9250_spi.h:52
struct spi_transaction spi_trans
Definition mpu9250_spi.h:53
#define MPU9250_BUFFER_LEN
Definition mpu9250_spi.h:39
@ MPU9250_SPI_CONF_UNINIT
Definition mpu9250_spi.h:43
@ MPU9250_SPI_CONF_SLAVES_CONFIGURE
Definition mpu9250_spi.h:47
@ MPU9250_SPI_CONF_DONE
Definition mpu9250_spi.h:48
@ MPU9250_SPI_CONF_I2C_MST_EN
Definition mpu9250_spi.h:46
@ MPU9250_SPI_CONF_I2C_MST_DELAY
Definition mpu9250_spi.h:45
@ MPU9250_SPI_CONF_I2C_MST_CLK
Definition mpu9250_spi.h:44
union Mpu9250_Spi::@347 data_accel
union Mpu9250_Spi::@348 data_rates
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.