10-27-2020 03:26 PM - edited 10-27-2020 03:36 PM
Hello,
I cannot seem to be able to get the initilization sequence of the BMA456 right. I'm using the bma4_v2.14.12 release of your API in our Zephyr-based project. I have motion_sensor.c for wrapping the hardware access.
At the end of the confugiration, INTERNAL_STATUS.message still is 0x00 (ASIC not initialized). I2C seems to be working because of the previous operation (reading CHIP_ID) do not fail.
I had to set dev.read_write_len = 2048 because out target's DMA cannot handle the complete config file burst write.
How can I fix this issue? Please find below my motion_sensor.c and the trace our application produced.
[00:00:00.202,789] [0m<inf> bma456: Read from 0x0: 0x16[0m
[00:00:00.203,582] [0m<inf> bma456: Read from 0x7c: 0x2[0m
[00:00:00.204,315] [0m<inf> bma456: Write to 0x7c: 0x2[0m
[00:00:00.204,559] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.205,352] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.206,542] [0m<inf> bma456: Write to 0x59: 0x0[0m
[00:00:00.206,787] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.208,038] [0m<inf> bma456: Write to 0x5b: 0x0[0m
[00:00:00.208,374] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.209,533] [0m<inf> bma456: Write to 0x5c: 0x0[0m
[00:00:00.209,777] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.419,219] [0m<inf> bma456: Write 2048 bytes to 0x5e[0m
[00:00:00.419,464] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.420,806] [0m<inf> bma456: Write to 0x5b: 0x0[0m
[00:00:00.421,020] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.422,180] [0m<inf> bma456: Write to 0x5c: 0x40[0m
[00:00:00.422,424] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.632,049] [0m<inf> bma456: Write 2048 bytes to 0x5e[0m
[00:00:00.633,056] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.635,345] [0m<inf> bma456: Write to 0x5b: 0x0[0m
[00:00:00.636,352] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.638,427] [0m<inf> bma456: Write to 0x5c: 0x80[0m
[00:00:00.639,526] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.850,646] [0m<inf> bma456: Write 2048 bytes to 0x5e[0m
[00:00:00.851,745] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.853,820] [0m<inf> bma456: Write to 0x59: 0x1[0m
[00:00:00.854,797] [0m<inf> bma456: Sleeping for 450 us[0m
[00:00:00.856,353] [0m<inf> bma456: Sleeping for 150000 us[0m
[00:00:01.008,361] [0m<inf> bma456: Read from 0x2a: 0x0[0m
[00:00:01.009,246] [1;31m<err> bma456: bma456_write_config_file failed: -5[0m
#include "motion_sensor.h"
#include <bma456/bma456.h>
#include <device.h>
#include <logging/log.h>
#include <drivers/i2c.h>
LOG_MODULE_REGISTER(bma456, CONFIG_GPS_CONTROL_LOG_LEVEL);
#define MOTION_SENSOR_I2C_ADDR (0x18)
#define DMA_MAX_TRANSFER_SIZE (2048)
static struct bma4_dev bma456;
static uint8_t i2c_buf[DMA_MAX_TRANSFER_SIZE];
/*!
* @brief Bus communication function pointer which should be mapped to
* the platform specific read functions of the user
*
* @param[in] reg_addr : Register address from which data is read.
* @param[out] read_data : Pointer to data buffer where read data is stored.
* @param[in] len : Number of bytes of data to be read.
* @param[in, out] intf_ptr : Void pointer that can enable the linking of descriptors
* for interface related call backs.
*
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
static BMA4_INTF_RET_TYPE motion_sensor_bus_read(uint8_t reg_addr, uint8_t *read_data, uint32_t len, void *intf_ptr) {
int ret;
if (len <= 1) {
ret = i2c_reg_read_byte(intf_ptr, MOTION_SENSOR_I2C_ADDR, reg_addr, read_data);
} else {
ret = i2c_burst_read(intf_ptr, MOTION_SENSOR_I2C_ADDR, reg_addr, i2c_buf, len);
memcpy(read_data, i2c_buf, len);
}
if (ret) {
LOG_ERR("Error reading %lu bytes from 0x%X: %d", len, reg_addr, ret);
} else {
if (len <= 1) {
LOG_INF("Read from 0x%X: 0x%X", reg_addr, *read_data);
} else {
LOG_INF("Read %lu bytes from 0x%X", len, reg_addr);
}
}
return ret;
}
/*!
* @brief Bus communication function pointer which should be mapped to
* the platform specific write functions of the user
*
* @param[in] reg_addr : Register address to which the data is written.
* @param[in] read_data : Pointer to data buffer in which data to be written
* is stored.
* @param[in] len : Number of bytes of data to be written.
* @param[in, out] intf_ptr : Void pointer that can enable the linking of descriptors
* for interface related call backs
*
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
static BMA4_INTF_RET_TYPE motion_sensor_bus_write(uint8_t reg_addr, const uint8_t *read_data, uint32_t len,
void *intf_ptr) {
int ret;
if (len <= 1) {
ret = i2c_reg_write_byte(intf_ptr, MOTION_SENSOR_I2C_ADDR, reg_addr, read_data[0]);
} else {
memcpy(i2c_buf, read_data, len);
ret = i2c_burst_write(intf_ptr, MOTION_SENSOR_I2C_ADDR, reg_addr, i2c_buf, len);
}
if (ret) {
LOG_ERR("Error writing %lu bytes to 0x%X: %d", len, reg_addr, ret);
} else {
if (len <= 1) {
LOG_INF("Write to 0x%X: 0x%X", reg_addr, *read_data);
} else {
LOG_INF("Write %lu bytes to 0x%X", len, reg_addr);
}
}
return ret;
}
/*!
* @brief Delay function pointer which should be mapped to
* delay function of the user
*
* @param[in] period : Delay in microseconds.
* @param[in, out] intf_ptr : Void pointer that can enable the linking of descriptors
* for interface related call backs
*
*/
static void motion_sensor_delay(uint32_t period, void *intf_ptr) {
LOG_INF("Sleeping for %lu us", period);
k_sleep(K_USEC(period));
}
int motion_sensor_init(const char *dev_name) {
int8_t ret;
struct device *i2c_dev = device_get_binding(dev_name);
if (NULL == i2c_dev) {
LOG_ERR("Cannot get device binding for %s", log_strdup(dev_name));
return -1;
}
bma456.intf = BMA4_I2C_INTF;
bma456.bus_read = motion_sensor_bus_read;
bma456.bus_write = motion_sensor_bus_write;
bma456.delay_us = motion_sensor_delay;
bma456.intf_ptr = i2c_dev;
bma456.read_write_len = 2048;
if ((ret = bma456_init(&bma456)) != 0) {
LOG_ERR("bma456_init failed: %d", ret);
return ret;
}
if ((ret = bma456_write_config_file(&bma456)) != 0) {
LOG_ERR("bma456_write_config_file failed: %d", ret);
return ret;
}
return ret;
}
Solved! Go to Solution.
04-05-2022 08:43 PM
Hi Aisha,
The i2c read / write functions for our github are for Bosch EVM boards.
If you are using your own board, you have to modify i2c read / write functions accordingly.
Thank you.
04-15-2022 11:24 AM - edited 04-15-2022 11:26 AM
Hello Minhwan,
Thank you for your replay,
i'm trying to modify these i2c functions to be able to work with zephyr the same way ( that is done in this thread). zephyr needs an object from type "device" to be able to use the i2c functions,and i think this is my problem here.
Aisha