Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Imu bmi088 spi #7

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions imu_bmi088_spi/imu_bmi088_spi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include "imu_bmi088_spi.h"

ImuBmi088Spi::ImuBmi088Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *accCsPort, uint16_t accCsPin, GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin)
:

_hspi(hspi),
_accCsPort(accCsPort),
_accCsPin(accCsPin),
_gyroCsPort(gyroCsPort),
_gyroCsPin(gyroCsPin) {}

/* Notes */
// | 0x00 is for write, | 0x80 is for read
// Accelerometer instruction has a 2nd dummy byte after instruction for reads
// Any array in UPPER_SNAKE_CASE functions as a constant variable

int ImuBmi088Spi::Reset() {
// setting the chip select pins high
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);
HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET);

/* Accelerometer softreset */
// Accelerometer will be in suspend mode afterwards
uint8_t ACC_SOFTRESET[2] = {0x7E | 0x00, 0xB6};

HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, ACC_SOFTRESET, 2, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);

/* Gyroscope softreset */
uint8_t GYRO_SOFTRESET[2] = {0x14 | 0x00, 0xB6};

HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, GYRO_SOFTRESET, 2, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET);

// Delay for Gyro_softreset to complete
HAL_Delay(30);

return 0;
}

int ImuBmi088Spi::Init() {
// setting the chip select pins high
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);
HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET);

/* Accelerometer power on sequence */
// Switches the Accelerometer from suspend to normal mode
uint8_t ACC_PWR_CONF[2] = {0x7C | 0x00, 0x00};

HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, ACC_PWR_CONF, 2, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);

// Switches Accelerometer on
// 0x04 for for accelerometer on
uint8_t ACC_PWR_CTRL[2] = {0x7D | 0x00, 0x04};

// spi write to ACC_PWR_CTRL register to move to normal mode
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, ACC_PWR_CTRL, 2, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);

// 1 ms delay after change to normal mode
HAL_Delay(1);

/* Setting Accelerometer range to +- 24g */
uint8_t ACC_RANGE[2] = {0x41 | 0x00, 0x03};

HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, ACC_RANGE, 2, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);
//

/* Gyro power normal power mode */
// Switches Gyro from suspend to normal mode
// 0x00 for set to normal mode
uint8_t gyro_Lpm1[2] = {0x11 | 0x00, 0x00};

HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, gyro_Lpm1, 2, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET);

// Delay to ensure state change
HAL_Delay(30);

/* Accelerometer Chip ID read */
// Dummy byte 0x00
uint8_t ACC_CHIP_ID[2] = {0x00 | 0x80, 0x00};
uint8_t accID[1] = {0};

HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, ACC_CHIP_ID, 2, SERIAL_TIMEOUT) != HAL_OK) return 1;
if (HAL_SPI_Receive(_hspi, accID, 1, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);

/* Gyroscope Chip ID read */
uint8_t GYRO_CHIP_ID[1] = {0x00 | 0x80};
uint8_t gyroID[1] = {0};

HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, GYRO_CHIP_ID, 1, SERIAL_TIMEOUT) != HAL_OK) return 1;
if (HAL_SPI_Receive(_hspi, gyroID, 1, SERIAL_TIMEOUT) != HAL_OK) return 1;
HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET);

/* Self check if device ID of gyro and accelerometer are correct */
if (accID[0] != 0x1E) return 2;
if (gyroID[0] != 0x0F) return 3;

return 0;
}

ImuBmi088Spi::Data ImuBmi088Spi::Read() {
ImuBmi088Spi::Data data;

/* Accelerometer data registers read */
uint8_t ACC_DATA_REGISTERS[2] = {0x12 | 0x80, 0x00};
uint8_t accelerometerData[6] = {0};

HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, ACC_DATA_REGISTERS, 2, SERIAL_TIMEOUT) != HAL_OK) return data;
if (HAL_SPI_Receive(_hspi, accelerometerData, 6, SERIAL_TIMEOUT) != HAL_OK) return data;
HAL_GPIO_WritePin(_accCsPort, _accCsPin, GPIO_PIN_SET);

/* Gyroscope data registers read */
uint8_t GYRO_DATA_REGISTERS[1] = {0x02 | 0x80};
uint8_t gyroscopeData[6] = {0};

HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_RESET);
if (HAL_SPI_Transmit(_hspi, GYRO_DATA_REGISTERS, 1, SERIAL_TIMEOUT) != HAL_OK) return data;
if (HAL_SPI_Receive(_hspi, gyroscopeData, 6, SERIAL_TIMEOUT) != HAL_OK) return data;
HAL_GPIO_WritePin(_gyroCsPort, _gyroCsPin, GPIO_PIN_SET);

// Acceleration and angular velocity data being attributed into the Data struct
data.accelerationX = ((accelerometerData[1] << 8) + (accelerometerData[0]));
data.accelerationY = ((accelerometerData[3] << 8) + (accelerometerData[2]));
data.accelerationZ = ((accelerometerData[5] << 8) + (accelerometerData[4]));

data.angularVelocityX = ((gyroscopeData[1] << 8) + (gyroscopeData[0]));
data.angularVelocityY = ((gyroscopeData[3] << 8) + (gyroscopeData[2]));
data.angularVelocityZ = ((gyroscopeData[5] << 8) + (gyroscopeData[4]));

return data;
}
92 changes: 92 additions & 0 deletions imu_bmi088_spi/imu_bmi088_spi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once

#if defined(STM32F1)
#include "stm32f1xx_hal.h"
#elif defined(STM32F4xx)
#include "stm32f4xx_hal.h"
#endif

#ifndef SERIAL_TIMEOUT
#define SERIAL_TIMEOUT 10
#endif

/* Datasheet */
/* https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi088-ds001.pdf */

class ImuBmi088Spi {
public:
struct Data {
// Angular velocity counterclockwise along x-axis, launch vehicle frame
// Units 6.1*10^-2 degree/s
int16_t angularVelocityX = 0xFFFF;

// Angular velocity counterclockwise along y-axis, launch vehicle frame
// Units 6.1*10^-2 degree/s
int16_t angularVelocityY = 0xFFFF;

// Angular velocity counterclockwise along z-axis, launch vehicle frame
// Units 6.1*10^-2 degree/s
int16_t angularVelocityZ = 0xFFFF;

// Acceleration along x-axis, launch vehicle frame
// Units: 7.3 * 10^-4 g
int16_t accelerationX = 0xFFFF;

// Acceleration along y-axis, launch vehicle frame
// Units: 7.3 * 10^-4 g
int16_t accelerationY = 0xFFFF;

// Acceleration along x-axis, launch vehicle frame
// Units: 7.3 * 10^-4 g
int16_t accelerationZ = 0xFFFF;
};

/**
* @param hspi SPI bus handler
* @param accCsPort chip select port accelerometer
* @param accCsPin chip select pin accelerometer
* @param gyroCsPort chip select port gyroscope
* @param gyroCsPin chip select pin gyroscope
*/

ImuBmi088Spi(SPI_HandleTypeDef *hspi, GPIO_TypeDef *accCsPort, uint16_t accCsPin, GPIO_TypeDef *gyroCsPort, uint16_t gyroCsPin);

/**
* @brief Resets the IMU
* @retval Operation status, 0 for success
* @retval Operation failure, 1 for SPI transmit/recieve failure
*/
int Reset();

/**
* @brief Initializes the IMU
* @retval Operation status, 0 for success
* @retval Operation failure, 1 for SPI transmit/recieve failure
* @retval Operation failure, 2 for accelerometer ID fault
* @retval Operation failure, 3 for gyroscope ID fault
*/
int Init();

/**
* @brief Reads Gyroscope and Acceleration data
* @retval Output is struct Data
* @retval if any values = FFFF, then ERROR
*/
Data Read();

private:
// SPI bus handler
SPI_HandleTypeDef *_hspi;

// Chip select port
GPIO_TypeDef *_accCsPort;

// chip select pin accelerometer
uint16_t _accCsPin;

// chip select port gyroscope
GPIO_TypeDef *_gyroCsPort;

// chip select pin gyroscope
uint16_t _gyroCsPin;
};
Loading