02-15-2021 11:03 AM - edited 02-15-2021 11:12 AM
Hi,
I'm using STM32L4 MCU (STM32L476G-EVAL) and BMI270 shuttle board.
Sometimes it works but mostly it fails to initialize. So I'm asking for your help.
My setting is as follows:
1. SPI 4-wire mode (STM32Cube_FW_L4_V1.16.0)
SPI_HandleTypeDef hSPI1; /* Inertial Management */
void MX_SPI_Init(void)
{
hSPI1.Instance = SPI1;
hSPI1.Init.Mode = SPI_MODE_MASTER;
hSPI1.Init.Direction = SPI_DIRECTION_2LINES;
hSPI1.Init.DataSize = SPI_DATASIZE_8BIT;
hSPI1.Init.CLKPolarity = SPI_POLARITY_LOW;
hSPI1.Init.CLKPhase = SPI_PHASE_1EDGE;
hSPI1.Init.NSS = SPI_NSS_SOFT;
hSPI1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; /* HSE 8MHz, Full-duplex, 750.0Kbps */
hSPI1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hSPI1.Init.TIMode = SPI_TIMODE_DISABLE;
hSPI1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hSPI1.Init.CRCPolynomial = 7;
hSPI1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hSPI1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
HAL_SPI_Init(&hSPI1);
}
2. dummy_byte (https://github.com/BoschSensortec/BMI270-Sensor-API, v2.63.1)
int8_t bmi270_init(struct bmi2_dev *dev)
{ if (dev->intf == BMI2_SPI_INTF) { dev->dummy_byte = 0;/*1*/ } }
3. common.c
#define BMI270_MAX_READ_WRITE_LEN 38
static SPI_HandleTypeDef *hSPI = &hSPI1;
static uint8_t spiBuf[BMI270_MAX_READ_WRITE_LEN+1];
BMI2_INTF_RETURN_TYPE bmi2_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t r;
if (len == 0 || len > BMI270_MAX_READ_WRITE_LEN)
return BMI2_E_OUT_OF_RANGE;
if (reg_data == NULL)
return BMI2_E_NULL_PTR;
GpioOutputOff(SPI_CS_BMI270_GPIO_PORT, SPI_CS_BMI270_GPIO_PIN);
spiBuf[0] = reg_addr;
r = HAL_SPI_Transmit(hSPI, spiBuf, 1, 1000);
//while(hSPI->State == HAL_SPI_STATE_BUSY); // wait for xmission complete
if (r == 0)
{
memset(spiBuf, 0x00, sizeof(spiBuf));
r = HAL_SPI_Receive(hSPI, spiBuf, len+1, 1000);
//while(hSPI->State == HAL_SPI_STATE_BUSY); // wait for xmission complete
memcpy(reg_data, &spiBuf[1], len); /* The first byte is dummy */
}
GpioOutputOn(SPI_CS_BMI270_GPIO_PORT, SPI_CS_BMI270_GPIO_PIN);
return (r == 0) ? BMI2_INTF_RET_SUCCESS : BMI2_E_COM_FAIL;
}
BMI2_INTF_RETURN_TYPE bmi2_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t r;
if (len == 0 || len > BMI270_MAX_READ_WRITE_LEN)
return BMI2_E_OUT_OF_RANGE;
if (reg_data == NULL)
return BMI2_E_NULL_PTR;
GpioOutputOff(SPI_CS_BMI270_GPIO_PORT, SPI_CS_BMI270_GPIO_PIN);
spiBuf[0] = reg_addr;
memcpy(&spiBuf[1], reg_data, len);
r = HAL_SPI_Transmit(hSPI, spiBuf, len+1, 1000);
//while(hSPI->State == HAL_SPI_STATE_BUSY); // wait for xmission complete
GpioOutputOn(SPI_CS_BMI270_GPIO_PORT, SPI_CS_BMI270_GPIO_PIN);
return (r == 0) ? BMI2_INTF_RET_SUCCESS : BMI2_E_COM_FAIL;
}
void bmi2_delay_us(uint32_t period, void *intf_ptr)
{
uint32_t msec = period / 1000U;
if (period % 1000U != 0U)
msec++;
vTaskDelay(msec); // I'm using FreeRTOS v202012.00-LTS
}
int8_t bmi2_interface_init(struct bmi2_dev *bmi, uint8_t intf)
{
memset(bmi, 0, sizeof(struct bmi2_dev));
bmi->intf = intf;
bmi->delay_us = bmi2_delay_us;
bmi->read_write_len = BMI270_MAX_READ_WRITE_LEN;
bmi->config_file_ptr = NULL; /* Assign to NULL to load the default config file */
bmi->read = bmi2_spi_read;
bmi->write = bmi2_spi_write;
return BMI2_OK;
}
4. application
res = bmi2_interface_init(&bmi2_dev, BMI2_SPI_INTF);
uint8_t chipId;
res = bmi2_get_regs(BMI2_CHIP_ID_ADDR, &chipId, 1, &bmi2_dev); // It does not work without this line
res = bmi270_init(&bmi2_dev);
5. spi packet
I'm attaching an excel file. I did not check all 8K data but I think the 8K data is correct. The "load_status" is not valid.
It worked only 3 times among hundreds trials.
Would you help me please?
Thanks,
Hugh
Solved! Go to Solution.
02-19-2021 03:08 AM
Hi Sir:
Did you get BMI270 chip_id?
Why did you set dev->dummy_byte = 0? dev->dummy_byte should be set 1 when choosing SPI communication.
I always use stm32f411 platform. If necessary, the related reference code can be shared.
02-19-2021 05:13 AM
Hi Jet,
Thanks a lot for your reply.
> Did you get BMI270 chip_id?
Yes, I get the correct chip_id. The previously attached "spi.xlsx" shows that all 8K communication is correct. Only the "load_status" is not valid.
> Why did you set dev->dummy_byte = 0? dev->dummy_byte should be set 1 when choosing SPI communication.
I moved it in to my "bmi2_spi_read" just for my test.
> I always use stm32f411 platform. If necessary, the related reference code can be shared.
Great! I'll get a STM32F411 EVM and start with it. Would you send me the reference code please?
Best regards,
Hugh (perceiv2@gmail.com)
02-19-2021 05:22 AM
02-19-2021 08:48 AM
Hi Jet,
Thank you very much for your reference code.
Before I get STM32F2 EVM, I've applied it to STM32L4 EVM.
The initialization was successful once but mostly it reports BMI2_E_CONFIG_LOAD or BMI2_E_DEV_NOT_FOUND.
I have a stupid question. I'm using a shuttle board labeled "BOSCH BMI260_A2".
The dealer told me that it is BMI270 shuttle board. Can I continue with that shuttle board?
Best regards,
Hugh