Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
bmi088_i2c.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Gautier Hattenberger <gautier.hattenberger@enac.fr>
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, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
28 #include "peripherals/bmi088_i2c.h"
29 
30 void bmi088_i2c_init(struct Bmi088_I2c *bmi, struct i2c_periph *i2c_p, uint8_t gyro_addr, uint8_t accel_addr)
31 {
32  /* set i2c_peripheral */
33  bmi->i2c_p = i2c_p;
34 
35  /* slave address */
36  bmi->gyro_trans.slave_addr = gyro_addr;
37  bmi->accel_trans.slave_addr = accel_addr;
38  /* set inital status: Success or Done */
41 
42  /* set default BMI088 config options */
44 
45  bmi->gyro_available = false;
46  bmi->accel_available = false;
47  bmi->config.initialized = false;
49 }
50 
51 
52 static void bmi088_i2c_write_to_reg(void *bmi, uint8_t _reg, uint8_t _val, uint8_t _type)
53 {
54  struct Bmi088_I2c *bmi_i2c = (struct Bmi088_I2c *)(bmi);
55  if (_type == BMI088_CONFIG_ACCEL) {
56  bmi_i2c->accel_trans.buf[0] = _reg;
57  bmi_i2c->accel_trans.buf[1] = _val;
58  i2c_transmit(bmi_i2c->i2c_p, &(bmi_i2c->accel_trans), bmi_i2c->accel_trans.slave_addr, 2);
59  } else if (_type == BMI088_CONFIG_GYRO) {
60  bmi_i2c->gyro_trans.buf[0] = _reg;
61  bmi_i2c->gyro_trans.buf[1] = _val;
62  i2c_transmit(bmi_i2c->i2c_p, &(bmi_i2c->gyro_trans), bmi_i2c->gyro_trans.slave_addr, 2);
63  }
64 }
65 
66 // Configuration function called once before normal use
68 {
70  bmi->config.init_status++;
72  bmi088_send_config(bmi088_i2c_write_to_reg, (void *)bmi, &(bmi->config));
73  }
74  }
75 }
76 
77 void bmi088_i2c_read(struct Bmi088_I2c *bmi)
78 {
79  if (bmi->config.initialized &&
80  bmi->gyro_trans.status == I2CTransDone &&
82  /* read gyro */
84  i2c_transceive(bmi->i2c_p, &(bmi->gyro_trans), bmi->gyro_trans.slave_addr, 1, 6); //9);
85  /* read accel */
87  i2c_transceive(bmi->i2c_p, &(bmi->accel_trans), bmi->accel_trans.slave_addr, 1, 6); // 12);
88  }
89 }
90 
91 #define Int16FromBuf(_buf,_idx) ((int16_t)((_buf[_idx+1]<<8) | _buf[_idx]))
92 
93 void bmi088_i2c_event(struct Bmi088_I2c *bmi)
94 {
95  if (bmi->config.initialized) {
96  // Check gyro read
97  if (bmi->gyro_trans.status == I2CTransFailed) {
99  } else if (bmi->gyro_trans.status == I2CTransSuccess) {
100  // Successfull reading
101  //if (bit_is_set(bmi->gyro_trans.buf[8], 7)) {
102  // new data
103  bmi->data_rates.rates.p = Int16FromBuf(bmi->gyro_trans.buf, 0);
104  bmi->data_rates.rates.q = Int16FromBuf(bmi->gyro_trans.buf, 2);
105  bmi->data_rates.rates.r = Int16FromBuf(bmi->gyro_trans.buf, 4);
106  bmi->gyro_available = true;
107  //}
109  }
110  // Check accel read
111  if (bmi->accel_trans.status == I2CTransFailed) {
113  } else if (bmi->accel_trans.status == I2CTransSuccess) {
114  // Successfull reading
115  //if (bit_is_set(bmi->accel_trans.buf[11], 7)) {
116  // new data
117  bmi->data_accel.vect.x = Int16FromBuf(bmi->accel_trans.buf, 0);
118  bmi->data_accel.vect.y = Int16FromBuf(bmi->accel_trans.buf, 2);
119  bmi->data_accel.vect.z = Int16FromBuf(bmi->accel_trans.buf, 4);
120  bmi->accel_available = true;
121  //}
123  }
124  } else if (bmi->config.init_status != BMI088_CONF_UNINIT) { // Configuring but not yet initialized
126  // Accel config not finished
127  switch (bmi->accel_trans.status) {
128  case I2CTransFailed:
129  bmi->config.init_status--; // Retry config (TODO max retry)
130  /* Falls through. */
131  case I2CTransSuccess:
132  case I2CTransDone:
133  bmi088_send_config(bmi088_i2c_write_to_reg, (void *)bmi, &(bmi->config));
134  break;
135  default:
136  break;
137  }
138  }
139  else {
140  // gyro config not finished
141  switch (bmi->gyro_trans.status) {
142  case I2CTransFailed:
143  bmi->config.init_status--; // Retry config (TODO max retry)
144  /* Falls through. */
145  case I2CTransSuccess:
146  case I2CTransDone:
147  bmi088_send_config(bmi088_i2c_write_to_reg, (void *)bmi, &(bmi->config));
148  if (bmi->config.initialized) {
149  bmi->gyro_trans.status = I2CTransDone;
150  }
151  break;
152  default:
153  break;
154  }
155  }
156  }
157 }
158 
BMI088_GYRO_RATE_X_LSB
#define BMI088_GYRO_RATE_X_LSB
Definition: bmi088_regs.h:73
BMI088_CONF_UNINIT
@ BMI088_CONF_UNINIT
Definition: bmi088.h:97
i2c_transaction::buf
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
bmi088_set_default_config
void bmi088_set_default_config(struct Bmi088Config *c)
Definition: bmi088.c:61
Bmi088_I2c::config
struct Bmi088Config config
Definition: bmi088_i2c.h:51
bmi088_i2c_init
void bmi088_i2c_init(struct Bmi088_I2c *bmi, struct i2c_periph *i2c_p, uint8_t gyro_addr, uint8_t accel_addr)
Definition: bmi088_i2c.c:30
BMI088_CONFIG_GYRO
#define BMI088_CONFIG_GYRO
Definition: bmi088.h:109
bmi088_i2c.h
Bmi088_I2c::accel_available
volatile bool accel_available
accel data ready flag
Definition: bmi088_i2c.h:42
Bmi088_I2c::i2c_p
struct i2c_periph * i2c_p
Definition: bmi088_i2c.h:38
Bmi088_I2c::data_accel
union Bmi088_I2c::@308 data_accel
I2CTransFailed
@ I2CTransFailed
transaction failed
Definition: i2c.h:58
bmi088_i2c_start_configure
void bmi088_i2c_start_configure(struct Bmi088_I2c *bmi)
Definition: bmi088_i2c.c:67
Bmi088_I2c::accel_trans
struct i2c_transaction accel_trans
i2c transaction for accel
Definition: bmi088_i2c.h:40
Bmi088_I2c::data_rates
union Bmi088_I2c::@309 data_rates
Bmi088Config::init_status
enum Bmi088ConfStatus init_status
init status
Definition: bmi088.h:119
BMI088_CONF_ACCEL_PWR_CTRL
@ BMI088_CONF_ACCEL_PWR_CTRL
Definition: bmi088.h:101
bmi088_i2c_write_to_reg
static void bmi088_i2c_write_to_reg(void *bmi, uint8_t _reg, uint8_t _val, uint8_t _type)
Definition: bmi088_i2c.c:52
BMI088_ACCEL_X_LSB
#define BMI088_ACCEL_X_LSB
Definition: bmi088_regs.h:38
I2CTransSuccess
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition: i2c.h:57
i2c_transmit
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition: i2c.c:324
Bmi088_I2c::gyro_trans
struct i2c_transaction gyro_trans
i2c transaction for gyro
Definition: bmi088_i2c.h:39
bmi088_i2c_read
void bmi088_i2c_read(struct Bmi088_I2c *bmi)
Definition: bmi088_i2c.c:77
bmi088_i2c_event
void bmi088_i2c_event(struct Bmi088_I2c *bmi)
Definition: bmi088_i2c.c:93
i2c_transceive
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition: i2c.c:344
uint8_t
unsigned char uint8_t
Definition: types.h:14
Bmi088Config::initialized
bool initialized
config done flag
Definition: bmi088.h:120
i2c_transaction::status
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
Bmi088_I2c
Definition: bmi088_i2c.h:37
Bmi088_I2c::gyro_available
volatile bool gyro_available
gyro data ready flag
Definition: bmi088_i2c.h:41
i2c_transaction::slave_addr
uint8_t slave_addr
Slave address.
Definition: i2c.h:104
Int16FromBuf
#define Int16FromBuf(_buf, _idx)
Definition: bmi088_i2c.c:91
bmi088_send_config
void bmi088_send_config(Bmi088ConfigSet bmi_set, void *bmi, struct Bmi088Config *config)
Configuration sequence called once before normal use.
Definition: bmi088.c:70
I2CTransDone
@ I2CTransDone
transaction set to done by user level
Definition: i2c.h:59
i2c_periph
Definition: i2c.h:144
BMI088_CONFIG_ACCEL
#define BMI088_CONFIG_ACCEL
Definition: bmi088.h:108