Hello everyone,
I am currently trying to get the BMI160 Sensor to work. It is connected trough SPI to the main processor. I would like to use the Driver provided (https://github.com/BoschSensortec/BMI160_driver), but do not really know how to continue.
In the readme file it is written that first I have to create a bmi160_dev struct. Then I have to initialise the.read and the .write functions. I do not really understand what is asked here.
Is that just the function one usually uses to read or write per SPI? As an argument I get the registry adress, the data and its length and then I just need to call some HAL_SPI_TRANSMIT or HAL_SPI_RECEIVE (now for STM32)?
And one more question: Is the length the length of the transmitted data in bytes without the adress? (So if I have 16 bits -> 8 for the adress and write/read and 8 for the data the length would be 1?)
Thank you very much for your help!
Sincerely
Sam
Hi Samfirex,
the read and write functions require function pointers to function of yours that are able to read/write multiple bytes from/to the SPI.
In the file bmi160_defs.h lines 714, 715 you can see how these functions must be defined
typedef int8_t (*bmi160_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
typedef void (*bmi160_delay_fptr_t)(uint32_t period);
You mentioned yourself the arguments the function must implement.
These functions are then called in "bmi160_get_regs" or "bmi160_get_regs", e.g.:
rslt = dev->read(dev->id, reg_addr, data, len);
The function for SPI read and write you have to provide can look like this (for an Arduino environment)
int8_t bmi_spiWriteBytes(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
SPISettings imuSpiSettings(8000000, MSBFIRST, SPI_MODE0);
SPI1.beginTransaction(imuSpiSettings);
//csPin = dev_addr -> chip_id
digitalWrite(SS_IMU_BMI, LOW); // Initiate communication
SPI1.transfer(reg_addr); // Send Address
for (int i = 0; i < len; i++)
{
SPI1.transfer(*(data + i)); // Transfer the data
}
digitalWrite(SS_IMU_BMI, HIGH); // Close communication
SPI1.endTransaction();
return 0;
}
int8_t bmi_spiReadBytes(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
SPISettings imuSpiSettings(8000000, MSBFIRST, SPI_MODE0);
SPI1.beginTransaction(imuSpiSettings);
digitalWrite(SS_IMU_BMI, LOW); // Initiate communication
SPI1.transfer(reg_addr); // Send Address
for (int i = 0; i < len; i++)
{
*(data + i) = SPI1.transfer(0x00); // request, read the data
}
digitalWrite(SS_IMU_BMI, HIGH); // Close communication
SPI1.endTransaction();
return 0;
}
You have to adapt these functions to match your controllers environment.
These functions you have to provide to the struct as pointers:
struct bmi160_dev sensor;
sensor.id = 0;
sensor.interface = BMI160_SPI_INTF;
sensor.chip_id = SS_IMU_BMI;
sensor.read = &bmi_spiReadBytes; // Function pointer to SPI read
sensor.write = &bmi_spiWriteBytes; // Function pointer to SPI write
sensor.delay_ms = &delay; // Function pointer to delay(ms) function
rslt = bmi160_init(&sensor);
Then you should be all set and you can start using the functions from the API like "bmi160_get_sensor_data(...)".
Hope it works for you.
Greetings Julian
1.Yes. The two functions must be initialized in order to read and write via SPI bus. You should also follow the SPI timing described in the BMI160 datasheet.
2.If you were talking about the example "rslt = bmi160_get_regs(reg_addr, &data, len, &sensor);", the len (length) indicates how many bytes of data you have read from the BMI160 reg map.