Paparazzi UAS  v5.0.5_stable-7-g4b8bbb7
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
mpu60x0_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 mpu60x0_spi_init(struct Mpu60x0_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 MPU60X0 config options */
57 
58  mpu->data_available = FALSE;
59  mpu->config.initialized = FALSE;
61 
63 }
64 
65 
66 static void mpu60x0_spi_write_to_reg(void* mpu, uint8_t _reg, uint8_t _val) {
67  struct Mpu60x0_Spi* mpu_spi = (struct Mpu60x0_Spi*)(mpu);
68  mpu_spi->spi_trans.output_length = 2;
69  mpu_spi->spi_trans.input_length = 0;
70  mpu_spi->tx_buf[0] = _reg;
71  mpu_spi->tx_buf[1] = _val;
72  spi_submit(mpu_spi->spi_p, &(mpu_spi->spi_trans));
73 }
74 
75 // Configuration function called once before normal use
77 {
79  mpu->config.init_status++;
82  }
83  }
84 }
85 
86 void mpu60x0_spi_read(struct Mpu60x0_Spi *mpu)
87 {
88  if (mpu->config.initialized && mpu->spi_trans.status == SPITransDone) {
89  mpu->spi_trans.output_length = 1;
90  mpu->spi_trans.input_length = 1 + mpu->config.nb_bytes;
91  /* set read bit and multiple byte bit, then address */
93  spi_submit(mpu->spi_p, &(mpu->spi_trans));
94  }
95 }
96 
97 #define Int16FromBuf(_buf,_idx) ((int16_t)((_buf[_idx]<<8) | _buf[_idx+1]))
98 
99 void mpu60x0_spi_event(struct Mpu60x0_Spi *mpu)
100 {
101  if (mpu->config.initialized) {
102  if (mpu->spi_trans.status == SPITransFailed) {
104  }
105  else if (mpu->spi_trans.status == SPITransSuccess) {
106  // Successfull reading
107  if (bit_is_set(mpu->rx_buf[1], 0)) {
108  // new data
109  mpu->data_accel.vect.x = Int16FromBuf(mpu->rx_buf, 2);
110  mpu->data_accel.vect.y = Int16FromBuf(mpu->rx_buf, 4);
111  mpu->data_accel.vect.z = Int16FromBuf(mpu->rx_buf, 6);
112  mpu->data_rates.rates.p = Int16FromBuf(mpu->rx_buf, 10);
113  mpu->data_rates.rates.q = Int16FromBuf(mpu->rx_buf, 12);
114  mpu->data_rates.rates.r = Int16FromBuf(mpu->rx_buf, 14);
115 
116  // if we are reading slaves, copy the ext_sens_data
117  if (mpu->config.nb_slaves > 0)
118  memcpy(mpu->data_ext, (void *) &(mpu->rx_buf[16]), mpu->config.nb_bytes - 15);
119 
120  mpu->data_available = TRUE;
121  }
123  }
124  }
125  else if (mpu->config.init_status != MPU60X0_CONF_UNINIT) { // Configuring but not yet initialized
126  switch (mpu->spi_trans.status) {
127  case SPITransFailed:
128  mpu->config.init_status--; // Retry config (TODO max retry)
129  case SPITransSuccess:
130  case SPITransDone:
132  if (mpu->config.initialized)
134  break;
135  default:
136  break;
137  }
138  }
139 }
140 
143 {
144  struct Mpu60x0_Spi* mpu_spi = (struct Mpu60x0_Spi*)(mpu);
145 
147  mpu_spi->slave_init_status++;
148 
149  switch (mpu_spi->slave_init_status) {
151  /* configure MPU I2C master clock and stop/start between slave reads */
152  mpu_set(mpu, MPU60X0_REG_I2C_MST_CTRL, ((1<<4) | mpu_spi->config.i2c_mst_clk));
153  mpu_spi->slave_init_status++;
154  break;
156  /* Set I2C slaves delayed sample rate */
157  mpu_set(mpu, MPU60X0_REG_I2C_MST_DELAY, mpu_spi->config.i2c_mst_delay);
158  mpu_spi->slave_init_status++;
159  break;
161  /* enable internal I2C master and disable primary I2C interface */
162  mpu_set(mpu, MPU60X0_REG_USER_CTRL, ((1 << MPU60X0_I2C_IF_DIS) |
163  (1 << MPU60X0_I2C_MST_EN)));
164  mpu_spi->slave_init_status++;
165  break;
167  /* configure first slave, only one slave supported so far */
168  if (mpu_spi->config.slaves[0].configure(mpu_set, mpu))
169  mpu_spi->slave_init_status++;
170  break;
172  return TRUE;
173  default:
174  break;
175  }
176  return FALSE;
177 }
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:152
void mpu60x0_spi_init(struct Mpu60x0_Spi *mpu, struct spi_periph *spi_p, uint8_t slave_idx)
Definition: mpu60x0_spi.c:31
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:149
struct Int16Rates rates
rates data as angular rates in gyro coordinate system
Definition: mpu60x0_spi.h:62
#define MPU60X0_REG_USER_CTRL
Definition: mpu60x0_regs.h:39
uint8_t input_length
number of data words to read
Definition: spi.h:145
enum Mpu60x0SpiSlaveInitStatus slave_init_status
Definition: mpu60x0_spi.h:67
#define MPU60X0_I2C_MST_EN
Definition: mpu60x0_regs.h:127
void mpu60x0_spi_start_configure(struct Mpu60x0_Spi *mpu)
Definition: mpu60x0_spi.c:76
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
CPHA = 1.
Definition: spi.h:69
volatile uint8_t rx_buf[MPU60X0_BUFFER_LEN]
Definition: mpu60x0_spi.h:55
void mpu60x0_spi_event(struct Mpu60x0_Spi *mpu)
Definition: mpu60x0_spi.c:99
uint8_t nb_slaves
number of used I2C slaves
Definition: mpu60x0.h:89
#define MPU60X0_REG_I2C_MST_CTRL
Definition: mpu60x0_regs.h:56
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:143
CPOL = 1.
Definition: spi.h:78
#define MPU60X0_BUFFER_LEN
Definition: mpu60x0_spi.h:39
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:148
#define FALSE
Definition: imu_chimu.h:141
enum SPITransactionStatus status
Definition: spi.h:156
union Mpu60x0_Spi::@26 data_rates
Mpu60x0I2cSlaveConfigure configure
Definition: mpu60x0.h:70
uint8_t data_ext[MPU60X0_BUFFER_EXT_LEN]
Definition: mpu60x0_spi.h:65
#define Int16FromBuf(_buf, _idx)
Definition: mpu60x0_spi.c:97
#define MPU60X0_SPI_READ
Definition: mpu60x0_regs.h:35
struct Mpu60x0Config config
Definition: mpu60x0_spi.h:66
Definition: spi.h:84
#define MPU60X0_I2C_IF_DIS
Definition: mpu60x0_regs.h:126
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:153
bool_t spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit a spi transaction.
Definition: spi_arch.c:469
#define MPU60X0_REG_I2C_MST_DELAY
Definition: mpu60x0_regs.h:58
uint8_t nb_bytes
number of bytes to read starting with MPU60X0_REG_INT_STATUS
Definition: mpu60x0.h:80
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:151
bool_t initialized
config done flag
Definition: mpu60x0.h:82
static void mpu60x0_spi_write_to_reg(void *mpu, uint8_t _reg, uint8_t _val)
Definition: mpu60x0_spi.c:66
uint8_t output_length
number of data words to write
Definition: spi.h:146
union Mpu60x0_Spi::@25 data_accel
volatile uint8_t tx_buf[2]
Definition: mpu60x0_spi.h:54
enum Mpu60x0ConfStatus init_status
init status
Definition: mpu60x0.h:81
void mpu60x0_spi_read(struct Mpu60x0_Spi *mpu)
Definition: mpu60x0_spi.c:86
struct Mpu60x0I2cSlave slaves[5]
I2C slaves.
Definition: mpu60x0.h:90
bool_t mpu60x0_configure_i2c_slaves(Mpu60x0ConfigSet mpu_set, void *mpu)
Configure I2C slaves of the MPU.
Definition: mpu60x0_spi.c:142
#define TRUE
Definition: imu_chimu.h:144
uint8_t i2c_mst_delay
MPU I2C slaves delayed sample rate.
Definition: mpu60x0.h:92
void mpu60x0_send_config(Mpu60x0ConfigSet mpu_set, void *mpu, struct Mpu60x0Config *config)
Configuration sequence called once before normal use.
Definition: mpu60x0.c:51
#define MPU60X0_REG_INT_STATUS
Definition: mpu60x0_regs.h:89
enum Mpu60x0MstClk i2c_mst_clk
MPU I2C master clock speed.
Definition: mpu60x0.h:91
volatile bool_t data_available
data ready flag
Definition: mpu60x0_spi.h:56
unsigned char uint8_t
Definition: types.h:14
slave is selected before transaction and unselected after
Definition: spi.h:57
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:147
Definition: spi.h:119
struct spi_periph * spi_p
Definition: mpu60x0_spi.h:52
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:144
void mpu60x0_set_default_config(struct Mpu60x0Config *c)
Definition: mpu60x0.c:32
SPICallback before_cb
NULL or function called before the transaction.
Definition: spi.h:154
Driver for the MPU-60X0 using SPI.
struct Int16Vect3 vect
accel data vector in accel coordinate system
Definition: mpu60x0_spi.h:58
void(* Mpu60x0ConfigSet)(void *mpu, uint8_t _reg, uint8_t _val)
Configuration function prototype.
Definition: mpu60x0.h:64
struct spi_transaction spi_trans
Definition: mpu60x0_spi.h:53
SPICallback after_cb
NULL or function called after the transaction.
Definition: spi.h:155