07-22-2019 08:58 AM - edited 07-22-2019 09:16 AM
Hi,
I'm working with the BMI270 with STM32F072 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 error I get is always `BMI2_E_CONFIG_LOAD`.
Following my initialization code:
// Enable spi interface
bmi270_dev.read = bm_spi_read;
bmi270_dev.write = bm_spi_write;
bmi270_dev.delay_us = delayUs;
bmi270_dev.read_write_len = SPI_BUFF_SZ;
bmi270_dev.intf = BMI2_SPI_INTERFACE;
bmi270_dev.dev_id = 0;
bmi270_dev.dummy_byte = 1;
bmi270_dev.config_file_ptr = NULL; // Load the default `bmi270_config_file` hard coded in the driver
// Initialize bmi270
rslt = bmi270_init(&bmi270_dev);
if (rslt != BMI2_OK)
return rslt;
where:
int8_t bm_spi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t len) {
UNUSED(dev_addr);
if( len > SPI_BUFF_SZ ) {
Error_Handler();
}
uint8_t rxarr[SPI_BUFF_SZ] = { reg_addr };
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(hspi_bmi, rxarr, rxarr,
len + 1,
COMM_DELAY);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_SET);
memcpy(data, rxarr + 1, len);
return (status == HAL_OK ? BMI2_OK : BMI2_E_COM_FAIL);
}
int8_t bm_spi_write(uint8_t dev_addr, uint8_t reg_addr, const uint8_t *data, uint16_t len) {
UNUSED(dev_addr);
if( len > SPI_BUFF_SZ ) {
Error_Handler();
}
uint8_t txarr[SPI_BUFF_SZ] = { reg_addr };
memcpy(txarr + 1, data, len);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef status = HAL_SPI_Transmit(hspi_bmi, txarr, len + 1,
COMM_DELAY);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_SET);
return (status == HAL_OK ? BMI2_OK : BMI2_E_COM_FAIL);
}
uint32_t getUs(void) {
uint32_t usTicks = HAL_RCC_GetSysClockFreq() / 1000000;
register uint32_t ms, cycle_cnt;
do {
ms = HAL_GetTick();
cycle_cnt = SysTick->VAL;
} while (ms != HAL_GetTick());
return (ms * 1000) + (usTicks * 1000 - cycle_cnt) / usTicks;
}
void delayUs(uint32_t micros) {
uint32_t start = getUs();
while (getUs()-start < (uint32_t) micros) {
asm("nop");
}
}
Thank you
Walter
Solved! Go to Solution.
07-22-2019 09:37 AM - edited 07-22-2019 09:38 AM
Hi Myzhar,
It seems that the implementation of your read/write or inversely the usage of bmi270_dev.read_write_len is incorrect. Either
Basically you will have an array out of bounds when you are at the max read/write length, as you do not account for the reg_addr parameter while copying the buffers.
If that doesn't fix the issue, kindly provide the configuration of the SPI bus configuration of the STM32 MCU, and if possible and Saleae log of the communication.
Regards,
kgoveas
07-22-2019 10:58 AM
Hi kgoveas,
thank you for help.
I set SPI_BUFF_SZ as
`#define SPI_BUFF_SZ (1024+1)`
changing
bmi270_dev.read_write_len = SPI_BUFF_SZ-1;
then I fixed read and write function as
int8_t bm_spi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t len) {
UNUSED(dev_addr);
if( len > (SPI_BUFF_SZ-1) ) {
Error_Handler();
}
uint8_t rxarr[SPI_BUFF_SZ] = { reg_addr };
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(hspi_bmi, rxarr, rxarr, len + 1, COMM_DELAY);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_SET);
memcpy(data, rxarr + 1, len);
return (status == HAL_OK ? BMI2_OK : BMI2_E_COM_FAIL);
}
int8_t bm_spi_write(uint8_t dev_addr, uint8_t reg_addr, const uint8_t *data, uint16_t len) {
UNUSED(dev_addr);
if( len > (SPI_BUFF_SZ-1) ) {
Error_Handler();
}
uint8_t txarr[SPI_BUFF_SZ] = { reg_addr };
memcpy(txarr + 1, data, len);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef status = HAL_SPI_Transmit(hspi_bmi, txarr, len, COMM_DELAY);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_SET);
return (status == HAL_OK ? BMI2_OK : BMI2_E_COM_FAIL);
}
The read seems to work because I can correctly read the chip-id:
// ----> Chip-ID Init test
uint8_t chip_id;
rslt = bmi2_get_regs(BMI2_CHIP_ID_ADDR, &chip_id, 1, &bmi270_dev);
if (rslt != BMI2_OK && chip_id != BMI270_CHIP_ID)
return rslt;
// <---- Chip-ID Init test
but initialization fails getting the same LOAD CONFIG error.
The configuration of the SPI:
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
Thank you again,
Walter
07-22-2019 11:27 AM
Thank you kgoveas,
you helped me to focus on the correct part of code where to search for the problem and I finally fixed it.
This is the correct write function:
int8_t bm_spi_write(uint8_t dev_addr, uint8_t reg_addr, const uint8_t *data, uint16_t len) {
UNUSED(dev_addr);
if( len > (SPI_BUFF_SZ-1) ) {
Error_Handler();
}
uint8_t txarr[SPI_BUFF_SZ] = { reg_addr };
memcpy(txarr + 1, data, len);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef status = HAL_SPI_Transmit(hspi_bmi, txarr, len+1, COMM_DELAY);
HAL_GPIO_WritePin(SPI_CS_N_GPIO_Port, SPI_CS_N_Pin, GPIO_PIN_SET);
return (status == HAL_OK ? BMI2_OK : BMI2_E_COM_FAIL);
}
A silly "+1" for the writing buffer lenght was missing in the "HAL_SPI_Transmit" calling.
Best regards,
Walter