Bosch Sensortec Community

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

    BMA456 initialization failure

    MBEonas
    Member

    BMA456 initialization failure

    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;
    }

     

    8 REPLIES 8
    Minhwan
    Community Moderator

    Re: BMA456 initialization failure

    Hello, 

     

    I don't understand what you mean "I had to set dev.read_write_len = 2048 because out target's DMA cannot handle the complete config file burst write."

    You mean that your system can't send DMA memory sequencely? ( 0 ~ 15, 16 ~ 31 bytes for 16 bytes each)

    Thanks, 

    MBEonas
    Member

    Re: BMA456 initialization failure


    For configuration file uploading, we offer burst write until 110 bytes. 


    I assumed from the datasheet that we had to write the whole config in one burst of 6kB. When you say "until 110 bytes", do you mean that bursts cannot be larger than 110 bytes or that they must be at least 110 bytes?


    However, I don't understand what you mean "I had to set dev.read_write_len = 2048 because out target's DMA cannot handle the complete config file burst write."

    You mean that your system can't send DMA memory sequencely? ( 0 ~ 15, 16 ~ 31 bytes for 16 bytes each)


    From my understanding of the I2C driver we use, the associated DMA machine only has a 12 bit counter, so we cannot send more than 4095 bytes in one I2C transfer. So by setting 

    read_write_len = 2048

    your API split up the transfer to 3 chunks of 2kB each which our I2C stack can handle.

    Update

    The error is the same with

    read_write_len = 110

    Update 2

    I still have the same problem when I use directly consecutive transfers to send all 6kB in one  burst.

    Is there anything I can check to rule out some common problems? What exactly would you expect the trace to look like on a successful initialization?

    Thank you for your quick response.

    Minhwan
    Community Moderator

    Re: BMA456 initialization failure

    Hello, 

     

    I need to correct my answer. The limitation of read wrtie length is only for bma456h, so it's not your case. 

    You can use it 2048 bytes, 6144 bytes as well. 

    Let's check step by step. After bma4_write_config_file function calling, did you get any error? 

    Could you capture your data and upload it? 

    I'd like to check whether your burst write function can tranfer properly or not. 

    Reading chip_id is only required signle byte, so you can't check it. 

    Thanks, 

     

    MBEonas
    Member

    Re: BMA456 initialization failure


    Let's check step by step. After bma4_write_config_file function calling, did you get any error? 


    I did not investigate further if the chip is functional after this function returned an error. I mean, the INTERNAL_STATUS.msg register clearly says that the chips is not configured at this point.


    Could you capture your data and upload it? 

    I'd like to check whether your burst write function can tranfer properly or not. 

    Reading chip_id is only required signle byte, so you can't check it. 

    I'll try to get a capture tomorrow but unfortunately, the I2C lines are burried quite good on our electronic.

    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