forked from boschsensortec/BMI08x_SensorAPI
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdrv_bmi088.c
268 lines (237 loc) · 7.85 KB
/
drv_bmi088.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "stm32f4xx_hal.h"
#include "main.h"
#include "drv_bmi088.h"
/******************************************************************************/
/*! Macro definitions */
#define BMI088_SPI SPI1
#define BMI088_SPI_ACCEL 0
#define BMI088_SPI_GYRO 1
//ACCEL_CS = PA4, GYRO_CS = PB0(board c)
#define BMI088_ACCEL_NS_L HAL_GPIO_WritePin(CS1_ACCEL_GPIO_Port, CS1_ACCEL_Pin, GPIO_PIN_RESET);
#define BMI088_ACCEL_NS_H HAL_GPIO_WritePin(CS1_ACCEL_GPIO_Port, CS1_ACCEL_Pin, GPIO_PIN_SET);
#define BMI088_GYRO_NS_L HAL_GPIO_WritePin(CS1_GYRO_GPIO_Port, CS1_GYRO_Pin, GPIO_PIN_RESET);
#define BMI088_GYRO_NS_H HAL_GPIO_WritePin(CS1_GYRO_GPIO_Port, CS1_GYRO_Pin, GPIO_PIN_SET);
#define BMI08X_READ_WRITE_LEN UINT8_C(64)
#define BMI08X_TIMEOUT_CNT 1680000
/******************************************************************************/
/*! Static variable definition */
/*! Variable that holds the I2C device address or SPI chip selection for accel */
uint8_t acc_dev_add;
/*! Variable that holds the I2C device address or SPI chip selection for gyro */
uint8_t gyro_dev_add;
/******************************************************************************/
/*! User interface functions */
//extern SPI_HandleTypeDef hspi1;
uint8_t spi_rw_byte(uint8_t byte){
uint32_t timeout_cnt = 0;
SET_BIT(BMI088_SPI->CR1, SPI_CR1_SPE);
while((BMI088_SPI->SR & SPI_SR_TXE) == RESET){
if(timeout_cnt < BMI08X_TIMEOUT_CNT){
timeout_cnt++;
}else return 0;
}
BMI088_SPI->DR = byte;
timeout_cnt = 0;
while((BMI088_SPI->SR & SPI_SR_RXNE) == RESET){
if(timeout_cnt < BMI08X_TIMEOUT_CNT){
timeout_cnt++;
}else return 0;
}
return BMI088_SPI->DR;
// uint8_t rx;
// HAL_SPI_TransmitReceive(&hspi1,&byte,&rx,1,200);
// return rx;
}
/*!
* Delay function for stm32(systick)
*/
void bmi08x_delay_us(uint32_t period, void *intf_ptr)
{
uint32_t tick_start,tick_now,reload;
uint32_t tick_cnt = 0;
reload = SysTick->LOAD;
period = period * 168;
tick_start = SysTick->VAL;
while (1)
{
tick_now = SysTick->VAL;
if (tick_now != tick_start)
{
if (tick_now < tick_start){
tick_cnt += tick_start - tick_now;
}else{
tick_cnt += reload - tick_now + tick_start;
}
tick_start = tick_now;
if (tick_cnt >= period){ break; }
}
}
}
/*!
* SPI read function for stm32
*/
BMI08X_INTF_RET_TYPE bmi08x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_addr = *(uint8_t*)intf_ptr;
if(dev_addr == BMI088_SPI_ACCEL){
BMI088_ACCEL_NS_L;
bmi08x_delay_us(2,intf_ptr);
spi_rw_byte(reg_addr);
//spi_rw_byte(reg_addr);
while (len != 0){
*reg_data = spi_rw_byte(0x55);
reg_data++;len--;
}
BMI088_ACCEL_NS_H;
bmi08x_delay_us(2,intf_ptr);
}else{
BMI088_GYRO_NS_L;
bmi08x_delay_us(2,intf_ptr);
spi_rw_byte(reg_addr);
//spi_rw_byte(reg_addr);
while (len != 0){
*reg_data = spi_rw_byte(0x55);
reg_data++;len--;
}
BMI088_GYRO_NS_H;
bmi08x_delay_us(2,intf_ptr);
}
return 0;
}
/*!
* SPI write function for stm32
*/
BMI08X_INTF_RET_TYPE bmi08x_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_addr = *(uint8_t*)intf_ptr;
if(dev_addr == BMI088_SPI_ACCEL){
BMI088_ACCEL_NS_L;
bmi08x_delay_us(2,intf_ptr);
spi_rw_byte(reg_addr);
while (len != 0){
spi_rw_byte(*reg_data);
reg_data++;len--;
}
BMI088_ACCEL_NS_H;
//idle time between write access(typ. 2us)
bmi08x_delay_us(10,intf_ptr);
}else{
BMI088_GYRO_NS_L;
bmi08x_delay_us(2,intf_ptr);
spi_rw_byte(reg_addr);
while (len != 0){
spi_rw_byte(*reg_data);
reg_data++;len--;
}
BMI088_GYRO_NS_H;
//idle time between write access(typ. 2us)
bmi08x_delay_us(10,intf_ptr);
}
return 0;
}
/*!
* @brief Function to select the interface between SPI and I2C.
*
*/
int8_t bmi08x_interface_init(struct bmi08x_dev *bmi08x, uint8_t intf, enum bmi08x_variant variant)
{
int8_t rslt = BMI08X_OK;
if (bmi08x != NULL)
{
/* Bus configuration : I2C */
if (intf == BMI08X_I2C_INTF)
{
//printf("I2C Interface \n");
/* To initialize the user I2C function */
// acc_dev_add = BMI08X_ACCEL_I2C_ADDR_PRIMARY;
// gyro_dev_add = BMI08X_GYRO_I2C_ADDR_PRIMARY;
// bmi08x->intf = BMI08X_I2C_INTF;
// bmi08x->read = bmi08x_i2c_read;
// bmi08x->write = bmi08x_i2c_write;
return BMI08X_E_FEATURE_NOT_SUPPORTED;
}
/* Bus configuration : SPI */
else if (intf == BMI08X_SPI_INTF)
{
//printf("SPI Interface \n");
/* To initialize the user SPI function */
bmi08x->intf = BMI08X_SPI_INTF;
bmi08x->read = bmi08x_spi_read;
bmi08x->write = bmi08x_spi_write;
acc_dev_add = BMI088_SPI_ACCEL;
gyro_dev_add = BMI088_SPI_GYRO;
}
/* Selection of bmi085 or bmi088 sensor variant */
bmi08x->variant = variant;
/* Assign accel device address to accel interface pointer */
bmi08x->intf_ptr_accel = &acc_dev_add;
/* Assign gyro device address to gyro interface pointer */
bmi08x->intf_ptr_gyro = &gyro_dev_add;
/* Configure delay in microseconds */
bmi08x->delay_us = bmi08x_delay_us;
/* Configure max read/write length (in bytes) ( Supported length depends on target machine) */
bmi08x->read_write_len = BMI08X_READ_WRITE_LEN;
}
else
{
rslt = BMI08X_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief Prints the execution status of the APIs.
*/
//void bmi08x_error_codes_print_result(const char api_name[], int8_t rslt)
//{
// if (rslt != BMI08X_OK)
// {
// // printf("%s\t", api_name);
// // if (rslt == BMI08X_E_NULL_PTR)
// // {
// // printf("Error [%d] : Null pointer\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_COM_FAIL)
// // {
// // printf("Error [%d] : Communication failure\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_DEV_NOT_FOUND)
// // {
// // printf("Error [%d] : Device not found\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_OUT_OF_RANGE)
// // {
// // printf("Error [%d] : Out of Range\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_INVALID_INPUT)
// // {
// // printf("Error [%d] : Invalid input\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_CONFIG_STREAM_ERROR)
// // {
// // printf("Error [%d] : Config stream error\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_RD_WR_LENGTH_INVALID)
// // {
// // printf("Error [%d] : Invalid Read write length\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_INVALID_CONFIG)
// // {
// // printf("Error [%d] : Invalid config\r\n", rslt);
// // }
// // else if (rslt == BMI08X_E_FEATURE_NOT_SUPPORTED)
// // {
// // printf("Error [%d] : Feature not supported\r\n", rslt);
// // }
// // else if (rslt == BMI08X_W_FIFO_EMPTY)
// // {
// // printf("Warning [%d] : FIFO empty\r\n", rslt);
// // }
// // else
// // {
// // printf("Error [%d] : Unknown error code\r\n", rslt);
// // }
// }
//}