07-29-2020 04:10 PM
Hi,
I'm working with the BMI270 with PIC32MZ204BEFH064 over SPI. I'm using the Gihub driver and I have problems with the initialization of the devide.
Debugging the code I noticed that the initialization fails when reading for the config files back after writing.
The "INTERNAL_STATUS (0x21)" value is 0x02 = init_err
The error I get is always `BMI2_E_CONFIG_LOAD`.
Following my initialization code:
#define SPI_BUFF_SZ (8+1)
void user_delay_us(uint32_t period_us, void *intf_ptr)
{
/* Wait for a period amount of microseconds. */
DelayUs((unsigned long int)period_us);
}
/*!
* @brief This function is for writing the sensor's registers through SPI bus.
*/
int8_t user_spi_reg_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr)
{
/* Write to registers using SPI. Return 0 for a successful execution. */
int i;
uint8_t tmp_TX_buf[SPI_BUFF_SZ];
// if( length > (SPI_BUFF_SZ-1) )
// {
// return -1; //YOSSI TODO- implement Error_Handler();
// }
tmp_TX_buf[0] = k_SPI_WRITE_REG_VAL | reg_addr;
memcpy(tmp_TX_buf + 1, reg_data, length);
LATEbits.LATE4 = 0; //CS BMI270 = 0;
TP4 = 0;
//FREEing THE SPI BUF
while (SPI2STATbits.SPIRBF)
{
tmp_TX_buf[0] = SPI2BUF;
}
SPI2BUF = tmp_TX_buf[0] & 0xFF;
while(!SPI2STATbits.SPIRBF);
tmp_TX_buf[0] = SPI2BUF;
for(i=0; i<length; i++)
{
SPI2BUF = tmp_TX_buf[1+i] & 0xFF;
while(!SPI2STATbits.SPIRBF);
tmp_TX_buf[1+i] = SPI2BUF;
}
LATEbits.LATE4 = 1; //CS BMI270 = 1;
TP4 = 1;
return 0;
}
/*!
* @brief This function is for reading the sensor's registers through SPI bus.
*/
int8_t user_spi_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr)
{
/* Read from registers using SPI. Return 0 for a successful execution. */
int i;
uint8_t tmp_TX_buf[10];//,CRM_RX_buf[100];
LATEbits.LATE4 = 0; //CS BMI270 = 0;
TP4 = 0;
tmp_TX_buf[0] = k_SPI_READ_REG_VAL | reg_addr;
//FREEing THE SPI BUF
while (SPI2STATbits.SPIRBF)
{
reg_data[0] = SPI2BUF;
}
SPI2BUF = tmp_TX_buf[0] & 0xFF;
while(!SPI2STATbits.SPIRBF);
reg_data[0] = SPI2BUF; //
for(i=0;i<length;i++)
{
SPI2BUF = tmp_TX_buf[i] & 0xFF;
while(!SPI2STATbits.SPIRBF);
reg_data[i] = SPI2BUF; //
}
//BMI270 = 1;
LATEbits.LATE4 = 1;
TP4 = 1;
return 0;
}
int8_t bmi2_interface_selection(struct bmi2_dev *dev)
{
int8_t rslt = BMI2_OK;
if (dev != NULL)
{
/* Select the interface for execution
* For I2C : BMI2_I2C_INTF
* For SPI : BMI2_SPI_INTF
*/
dev->intf = BMI2_SPI_INTF;
....
Solved! Go to Solution.
07-29-2020 05:28 PM
Hello yosibuc,
How do you assign values to this structure "struct bmi2_dev"?
The following is a reference code.
struct bmi2_dev bmi270dev;
main(void)
{
struct bmi2_dev *dev;
dev = &bmi270dev;
Init_BMI270(dev);
}
int8_t Init_BMI270(struct bmi2_dev *dev)
{
int8_t rslt = BMI2_OK;
dev->dev_id = 0x00,
dev->intf = BMI2_SPI_INTERFACE,
dev->read = (bmi2_read_fptr_t)SensorAPI_SPIx_Read,
dev->write = (bmi2_write_fptr_t)SensorAPI_SPIx_Write,
dev->delay_us = (bmi2_delay_fptr_t)DelayUs,
dev->read_write_len = 32,
dev->config_file_ptr = NULL;
rslt = bmi270_wh_init(dev);
if (rslt != BMI2_OK)
{
PDEBUG("bmi270_wh_init() failed, error code: %d\r\n", rslt);
return rslt;
}
...
}
07-30-2020 01:05 PM - edited 07-30-2020 01:14 PM
Hey BSTRobin
Seems as I'm using a diffent ref code, what ref code are you using?
the goal is similar. In the ref code I got from:https://github.com/BoschSensortec/BMI270-Sensor-API
1) in bmi207.c there's a method int8_t bmi270_init(struct bmi2_dev *dev) That is the method im useing.
/*!
* @brief This API:
* 1) updates the device structure with address of the configuration file.
* 2) Initializes BMI270 sensor.
* 3) Writes the configuration file.
* 4) Updates the feature offset parameters in the device structure.
* 5) Updates the maximum number of pages, in the device structure.
*/
int8_t bmi270_init(struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if (rslt == BMI2_OK)
{
/* Assign chip id of BMI270 */
dev->chip_id = BMI270_CHIP_ID;
/* get the size of config array */
dev->config_size = sizeof(bmi270_config_file);
/* Enable the variant specific features if any */
dev->variant_feature = BMI2_GYRO_CROSS_SENS_ENABLE | BMI2_CRT_RTOSK_ENABLE;
/* An extra dummy byte is read during SPI read */
if (dev->intf == BMI2_SPI_INTF)
{
dev->dummy_byte = 1;
}
else
{
dev->dummy_byte = 0;
}
/* If configuration file pointer is not assigned any address */
if (!dev->config_file_ptr)
{
/* Give the address of the configuration file array to
* the device pointer
*/
dev->config_file_ptr = bmi270_config_file;
}
/* Initialize BMI2 sensor */
rslt = bmi2_sec_init(dev);
if (rslt == BMI2_OK)
{
/* Assign the offsets of the feature input
* configuration to the device structure
*/
dev->feat_config = bmi270_feat_in;
/* Assign the offsets of the feature output to
* the device structure
*/
dev->feat_output = bmi270_feat_out;
/* Assign the maximum number of pages to the
* device structure
*/
dev->page_max = BMI270_MAX_PAGE_NUM;
/* Assign maximum number of input sensors/
* features to device structure
*/
dev->input_sens = BMI270_MAX_FEAT_IN;
/* Assign maximum number of output sensors/
* features to device structure
*/
dev->out_sens = BMI270_MAX_FEAT_OUT;
/* Get the gyroscope cross axis sensitivity */
rslt = bmi2_get_gyro_cross_sense(dev);
}
}
return rslt;
}
before calling bmi207_init(sturct bmi2_dev* dev), I'm calling bmi2_interface_selection(struct bmi2_dev *dev)
with the following code:
int8_t bmi2_interface_selection(struct bmi2_dev *dev)
{
int8_t rslt = BMI2_OK;
if (dev != NULL)
{
/* Select the interface for execution
* For I2C : BMI2_I2C_INTF
* For SPI : BMI2_SPI_INTF
*/
dev->intf = BMI2_SPI_INTF;
/* Bus configuration : I2C */
if (dev->intf == BMI2_I2C_INTF)
{
printf("I2C Interface \n");
/* To initialize the user I2C function */
bmi2_user_i2c_init();
dev_addr = BMI2_I2C_PRIM_ADDR;
dev->read = user_i2c_reg_read;
dev->write = user_i2c_reg_write;
}
/* Bus configuration : SPI */
else if (dev->intf == BMI2_SPI_INTF)
{
printf("SPI Interface \n");
/* To initialize the user SPI function */
bmi2_user_spi_init();
dev_addr = 0;
dev->read = user_spi_reg_read;
dev->write = user_spi_reg_write;
}
/* Assign device address to interface pointer */
dev->intf_ptr = &dev_addr;
/* Configure delay in microseconds */
dev->delay_us = user_delay_us;
/* Configure max read/write length (in bytes) ( Supported length depends on target machine) */
dev->read_write_len = SPI_BUFF_SZ;// - 1;//8;
/* Assign to NULL to load the default config file. */
dev->config_file_ptr = NULL;
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
this might give a better picture:
/* Status of api are returned to this variable. */
int8_t rslt;
//uint8_t tmpReg_data[3];
/*! Sensor initialization configuration. */
struct bmi2_dev bmi2_device;
CS7 = 1;
set_SPI270_5mhz();
/* Initialize the dev structure */
rslt = bmi2_interface_selection(&bmi2_device);
bmi2_error_codes_print_result(rslt);
/* Initialize bmi270. */
rslt = bmi270_init(&bmi2_device);
bmi2_error_codes_print_result(rslt);
2) I dont have a bmi270_wh_init(dev) method.
07-31-2020 04:01 AM
Hello ,
I used other software version. But it doesn't matter all version have same initialization procudure.
Macro definition SPI_BUFF_SZ was 9 in your code. Because of the following code, it is recommended to set it to be greater than 1 and a multiple of 2
/* Bytes written are multiples of 2 */
if ((dev->read_write_len % 2) != 0)
{
dev->read_write_len = dev->read_write_len - 1;
}
if (dev->read_write_len < 2)
{
dev->read_write_len = 2;
}
From the return value of your initialization code, the configuration file failed to be loaded. From BMI270 data sheet, it had dummy byte for SPI read communication. It means it needs to ignore the first dummy byte, and the actual return value is after the dummy byte.
uint8_t GTXBuffer[512], GRXBuffer[2048];
int8_t SensorAPI_SPIx_Read(uint8_t slave_address7, uint8_t subaddress, uint8_t *pBuffer, uint16_t ReadNumbr)
{
slave_address7 = slave_address7;
GTXBuffer[0] = subaddress | 0x80;
HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); // NSS low
//HAL_SPI_TransmitReceive(&hspi2, pTxData, pRxData, ReadNumbr+1, BUS_TIMEOUT); // timeout 1000msec;
HAL_SPI_TransmitReceive(&SPI_HANDLE, GTXBuffer, GRXBuffer, ReadNumbr+1, BUS_TIMEOUT); // timeout 1000msec;
while(SPI_HANDLE.State == HAL_SPI_STATE_BUSY); // wait for xmission complete
HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); // NSS high
memcpy(pBuffer, GRXBuffer+1, ReadNumbr);
return 0;
}
By the way, BMI270 SPI interface is incompatible with two mode: '00'[CPOL=0, CPHA=0], '11'[CPOL=1, CPHA=1]. When you initialized your PIC32 SPI interface, you need to choose one mode of 00 or 11.
08-02-2020 01:11 PM
Hey BSTRobin
thank you very much, It seems as the issue was the spi mode {CPOL, CPHA}.
Best Regards