Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    BMA456 initialization failure

    BMA456 initialization failure

    MBEonas
    Member

    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] <inf> bma456: Read from 0x0: 0x16
    [00:00:00.203,582] <inf> bma456: Read from 0x7c: 0x2
    [00:00:00.204,315] <inf> bma456: Write to 0x7c: 0x2
    [00:00:00.204,559] <inf> bma456: Sleeping for 450 us
    [00:00:00.205,352] <inf> bma456: Sleeping for 450 us
    [00:00:00.206,542] <inf> bma456: Write to 0x59: 0x0
    [00:00:00.206,787] <inf> bma456: Sleeping for 450 us
    [00:00:00.208,038] <inf> bma456: Write to 0x5b: 0x0
    [00:00:00.208,374] <inf> bma456: Sleeping for 450 us
    [00:00:00.209,533] <inf> bma456: Write to 0x5c: 0x0
    [00:00:00.209,777] <inf> bma456: Sleeping for 450 us
    [00:00:00.419,219] <inf> bma456: Write 2048 bytes to 0x5e
    [00:00:00.419,464] <inf> bma456: Sleeping for 450 us
    [00:00:00.420,806] <inf> bma456: Write to 0x5b: 0x0
    [00:00:00.421,020] <inf> bma456: Sleeping for 450 us
    [00:00:00.422,180] <inf> bma456: Write to 0x5c: 0x40
    [00:00:00.422,424] <inf> bma456: Sleeping for 450 us
    [00:00:00.632,049] <inf> bma456: Write 2048 bytes to 0x5e
    [00:00:00.633,056] <inf> bma456: Sleeping for 450 us
    [00:00:00.635,345] <inf> bma456: Write to 0x5b: 0x0
    [00:00:00.636,352] <inf> bma456: Sleeping for 450 us
    [00:00:00.638,427] <inf> bma456: Write to 0x5c: 0x80
    [00:00:00.639,526] <inf> bma456: Sleeping for 450 us
    [00:00:00.850,646] <inf> bma456: Write 2048 bytes to 0x5e
    [00:00:00.851,745] <inf> bma456: Sleeping for 450 us
    [00:00:00.853,820] <inf> bma456: Write to 0x59: 0x1
    [00:00:00.854,797] <inf> bma456: Sleeping for 450 us
    [00:00:00.856,353] <inf> bma456: Sleeping for 150000 us
    [00:00:01.008,361] <inf> bma456: Read from 0x2a: 0x0
    [00:00:01.009,246] <err> bma456: bma456_write_config_file failed: -5
    #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;
    }

     

    11 REPLIES 11

    Minhwan
    Community Moderator
    Community Moderator

    Yes, you are right, if the value of 0x2A register is 0x00, it means BMA456 isn't initialized yet. 

    I will check it once you upload it. 

    Thanks, 

    I found the issue while investigating the I2C.

    Our I2C driver inserted a start and stopp after writing the first byte (the register address) of the burst transfer. Once we got rid of this behaviour, the BMA456 responds correctly after initialization.

    Best Regards

    我使用STM32进行计步但是在对bma456写入配置时出错,在此前每一步都是成功的,但是去读0X2A的状态是0,这意味着并没有初始化,怎么回事? 我使用了IIc接口 请尽快回复 谢谢!

     附上我们的程序:

    @MBEonas

    Can you please suggest how to did you remove the start/stop condition after the first register write of the burst. Or how can I confirm if I am facing the same issue?

    Aisha
    Member

    Hello,

    may i ask how you performed the linkage for i2c read and write functions, i have some problem linking those, i tried to copy some of the bits from the code you provided, so i have the following:

    BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
    {
    uint8_t dev_addr = *(uint8_t*)intf_ptr;

    return i2c_burst_read(intf_ptr, 0x18, reg_addr, reg_data, len);

    }

    /*!
    * I2C write function map to COINES platform
    */
    BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
    {
    uint8_t dev_addr = *(uint8_t*)intf_ptr;
    return i2c_burst_write(intf_ptr, 0x18, reg_addr, reg_data, len);
    }

    and in the init function i have:

    struct device *i2c_dev = device_get_binding("I2C_2");

    and:

    bma->intf = BMA4_I2C_INTF;
    bma->bus_read = bma4_i2c_read;
    bma->bus_write = bma4_i2c_write;
    bma->intf_ptr = i2c_dev;

    i have a bus fault possabily cased by a null pointer some where. it would be great if you showed me the steps for doing this linkage.

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist