Paparazzi UAS  v5.12_stable-4-g9b43e9b
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 
31 void 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 */
39  mpu->spi_trans.dss = SPIDss8bit;
41  mpu->spi_trans.cdiv = SPIDiv64;
42 
44  mpu->spi_trans.slave_idx = slave_idx;
45  mpu->spi_trans.output_length = 2;
47  mpu->spi_trans.before_cb = NULL;
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 
66 static void mpu9250_spi_write_to_reg(void *mpu, uint8_t _reg, uint8_t _val)
67 {
68  struct Mpu9250_Spi *mpu_spi = (struct Mpu9250_Spi *)(mpu);
69  mpu_spi->spi_trans.output_length = 2;
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)
81  if (mpu->spi_trans.status == SPITransSuccess && mpu->rx_buf[1] == MPU9250_WHOAMI_REPLY) {
82  mpu->config.init_status++;
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 
96 void mpu9250_spi_read(struct Mpu9250_Spi *mpu)
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  case SPITransSuccess:
145  case SPITransDone:
146  mpu9250_send_config(mpu9250_spi_write_to_reg, (void *)mpu, &(mpu->config));
147  if (mpu->config.initialized) {
149  }
150  break;
151  default:
152  break;
153  }
154  }
155 }
156 
159 {
160  struct Mpu9250_Spi *mpu_spi = (struct Mpu9250_Spi *)(mpu);
161 
162  if (mpu_spi->slave_init_status == MPU9250_SPI_CONF_UNINIT) {
163  mpu_spi->slave_init_status++;
164  }
165 
166  switch (mpu_spi->slave_init_status) {
168  /* configure MPU I2C master clock and stop/start between slave reads */
169  mpu_set(mpu, MPU9250_REG_I2C_MST_CTRL, ((1 << 4) | mpu_spi->config.i2c_mst_clk));
170  mpu_spi->slave_init_status++;
171  break;
173  /* Set I2C slaves delayed sample rate */
174  mpu_set(mpu, MPU9250_REG_I2C_MST_DELAY, mpu_spi->config.i2c_mst_delay);
175  mpu_spi->slave_init_status++;
176  break;
178  /* enable internal I2C master and disable primary I2C interface */
179  mpu_set(mpu, MPU9250_REG_USER_CTRL, ((1 << MPU9250_I2C_IF_DIS) |
180  (1 << MPU9250_I2C_MST_EN)));
181  mpu_spi->slave_init_status++;
182  break;
184  /* configure each slave until all nb_slaves are done */
185  if (mpu_spi->config.nb_slave_init < mpu_spi->config.nb_slaves && mpu_spi->config.nb_slave_init < MPU9250_I2C_NB_SLAVES) {
186  // proceed to next slave if configure for current one returns true
187  if (mpu_spi->config.slaves[mpu_spi->config.nb_slave_init].configure(mpu_set, mpu)) {
188  mpu_spi->config.nb_slave_init++;
189  }
190  }
191  else {
192  /* all slave devies configured, continue MPU side configuration of I2C slave stuff */
193  mpu_spi->slave_init_status++;
194  }
195  break;
197  return true;
198  default:
199  break;
200  }
201  return false;
202 }
enum Mpu9250MstClk i2c_mst_clk
MPU I2C master clock speed.
Definition: mpu9250.h:146
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:149
Mpu9250I2cSlaveConfigure configure
Definition: mpu9250.h:123
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:153
volatile uint8_t tx_buf[2]
Definition: mpu9250_spi.h:54
#define MPU9250_REG_INT_STATUS
Definition: mpu9250_regs.h:93
uint16_t output_length
number of data words to write
Definition: spi.h:146
CPHA = 1.
Definition: spi.h:69
enum Mpu9250ConfStatus init_status
init status
Definition: mpu9250.h:135
uint8_t nb_bytes
number of bytes to read starting with MPU9250_REG_INT_STATUS
Definition: mpu9250.h:134
#define MPU9250_BUFFER_LEN
Definition: mpu9250_spi.h:39
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition: spi_arch.c:458
CPOL = 1.
Definition: spi.h:78
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:152
bool mpu9250_configure_i2c_slaves(Mpu9250ConfigSet mpu_set, void *mpu)
configure the registered I2C slaves
Definition: mpu9250_spi.c:158
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:144
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:148
void mpu9250_spi_event(struct Mpu9250_Spi *mpu)
Definition: mpu9250_spi.c:109
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
Driver for the MPU-9250 using SPI.
SPI peripheral structure.
Definition: spi.h:168
Definition: spi.h:84
enum Mpu9250SpiSlaveInitStatus slave_init_status
Definition: mpu9250_spi.h:67
void mpu9250_send_config(Mpu9250ConfigSet mpu_set, void *mpu, struct Mpu9250Config *config)
Configuration sequence called once before normal use.
Definition: mpu9250.c:81
void mpu9250_spi_init(struct Mpu9250_Spi *mpu, struct spi_periph *spi_p, uint8_t slave_idx)
Definition: mpu9250_spi.c:31
#define MPU9250_REG_I2C_MST_CTRL
Definition: mpu9250_regs.h:60
SPICallback after_cb
NULL or function called after the transaction.
Definition: spi.h:155
union Mpu9250_Spi::@319 data_accel
void(* Mpu9250ConfigSet)(void *mpu, uint8_t _reg, uint8_t _val)
Configuration function prototype.
Definition: mpu9250.h:117
uint8_t data_ext[MPU9250_BUFFER_EXT_LEN]
Definition: mpu9250_spi.h:65
void mpu9250_set_default_config(struct Mpu9250Config *c)
Definition: mpu9250.c:60
uint8_t nb_slaves
number of used I2C slaves
Definition: mpu9250.h:143
#define MPU9250_I2C_IF_DIS
Definition: mpu9250_regs.h:130
struct Mpu9250Config config
Definition: mpu9250_spi.h:66
uint16_t input_length
number of data words to read
Definition: spi.h:145
struct spi_periph * spi_p
Definition: mpu9250_spi.h:52
#define MPU9250_REG_I2C_MST_DELAY
Definition: mpu9250_regs.h:62
#define MPU9250_REG_USER_CTRL
Definition: mpu9250_regs.h:41
unsigned char uint8_t
Definition: types.h:14
#define MPU9250_I2C_MST_EN
Definition: mpu9250_regs.h:131
union Mpu9250_Spi::@320 data_rates
static void mpu9250_spi_write_to_reg(void *mpu, uint8_t _reg, uint8_t _val)
Definition: mpu9250_spi.c:66
struct Mpu9250I2cSlave slaves[MPU9250_I2C_NB_SLAVES]
I2C slaves.
Definition: mpu9250.h:145
void mpu9250_spi_read(struct Mpu9250_Spi *mpu)
Definition: mpu9250_spi.c:96
slave is selected before transaction and unselected after
Definition: spi.h:57
volatile bool data_available
data ready flag
Definition: mpu9250_spi.h:56
uint8_t nb_slave_init
number of already configured/initialized slaves
Definition: mpu9250.h:144
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:151
#define MPU9250_I2C_NB_SLAVES
Definition: mpu9250.h:52
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:147
Definition: spi.h:119
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:143
SPICallback before_cb
NULL or function called before the transaction.
Definition: spi.h:154
#define MPU9250_REG_WHO_AM_I
Definition: mpu9250_regs.h:120
bool initialized
config done flag
Definition: mpu9250.h:136
#define Int16FromBuf(_buf, _idx)
Definition: mpu9250_spi.c:107
struct spi_transaction spi_trans
Definition: mpu9250_spi.h:53
#define MPU9250_WHOAMI_REPLY
Definition: mpu9250_regs.h:121
volatile uint8_t rx_buf[MPU9250_BUFFER_LEN]
Definition: mpu9250_spi.h:55
#define MPU9250_SPI_READ
Definition: mpu9250_regs.h:37
uint8_t i2c_mst_delay
MPU I2C slaves delayed sample rate.
Definition: mpu9250.h:147
enum SPITransactionStatus status
Definition: spi.h:156
void mpu9250_spi_start_configure(struct Mpu9250_Spi *mpu)
Definition: mpu9250_spi.c:77