Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    Issues Configuring Motion Detection with BMA530

    Issues Configuring Motion Detection with BMA530

    winner8
    New Poster

    I’m working with the BMA530 interfaced with I2C on the STM32 and trying to configure any-motion detection on one axis (X-axis specifically). I’ve been following the process from the datasheet, but I’m encountering some issues:

    1. Register Verification: Most of the configuration registers are read back correctly, except the GENERIC_INT1 registers, which consistently fail to hold the expected values and are all 0's. I understand the feature engine update register bits are write-only, so it makes sense that the FEAT_ENG_UPDATE register is read as 0x00. 

    winner8_0-1723935692842.png

    2. Interrupt Issue: The interrupt is constantly triggering, even though the motion detection parameters should be set to reasonable values, and the chip is stationary. This might have something to do with problem #1. 

    Below is the main part of the initialization code, BMA530_Init(), that is called from my main function. The printRegisterValues() function is used to check if the configuration was successful. 

     

    void BMA530_ConfigureGenericInt1(void) 
    {
        uint8_t buf[3];
        uint8_t regValues[2];
    	
        /// Configure GENERIC_INTERRUPT1_1 (0x04): axis selection, comb_sel, slope_thres
        buf[0] = BMA530_REG_GENERIC_INT1_1;
        uint16_t register_value = (BMA530_GENERIC_INT1_AXIS_SEL_X | BMA530_GENERIC_INT1_COMB_SEL_OR | BMA530_GENERIC_INT1_SLOPE_THRES(3500));
        buf[1] = (register_value >> 😎 & 0xFF;
        buf[2] = register_value & 0xFF;
        HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 3, HAL_MAX_DELAY);
    
        // Configure GENERIC_INTERRUPT1_2 (0x05): acc_ref_up, criterion_sel, hysteresis
        buf[0] = BMA530_REG_GENERIC_INT1_2;
        register_value = BMA530_GENERIC_INT1_ACC_REF_UP | BMA530_GENERIC_INT1_CRITERION_SEL | BMA530_GENERIC_INT1_HYSTERESIS(50);
        buf[1] = (register_value >> 😎 & 0xFF;
        buf[2] = register_value & 0xFF;
        HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 3, HAL_MAX_DELAY);
    
        // Configure GENERIC_INTERRUPT1_3 (0x06): duration and wait time
        buf[0] = BMA530_REG_GENERIC_INT1_3;
        uint16_t duration_value = DURATION_500MS;
        uint16_t wait_time_value = WAIT_TIME_200MS;
        uint16_t combined_value = (wait_time_value << 13) | duration_value;
        buf[1] = (combined_value >> 😎 & 0xFF;
        buf[2] = combined_value & 0xFF;
        HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 3, HAL_MAX_DELAY);
    
        // Configure GENERIC_INTERRUPT1_4 (0x07): minimal quiet time
        buf[0] = BMA530_REG_GENERIC_INT1_4;
        uint16_t quiet_time_value = QUIET_TIME_MIN;
        buf[1] = (quiet_time_value >> 😎 & 0x1F;  // Only 5 bits used (upper 3 bits are reserved)
        buf[2] = quiet_time_value & 0xFF;
        HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 3, HAL_MAX_DELAY);
    }
    
    void BMA530_Init(void) 
    {
        uint8_t buf[2];
        uint8_t reg_value;
        HAL_StatusTypeDef ret;
    
        // Step 1: Disable the accelerometer before performing the soft reset
        buf[0] = BMA530_REG_ACC_CONF0;
        buf[1] = 0x00;  // Disable the accelerometer
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 2: Perform Soft Reset (0x7E)
        buf[0] = 0x7E;  // Soft-reset register
        buf[1] = 0xB6;  // Soft-reset command
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(100);  // Wait after reset
    
        // Step 3: Configure ACC_CONF0 (0x30) - Enable the accelerometer
        buf[0] = BMA530_REG_ACC_CONF0;
        buf[1] = 0x0F;  // Enable the accelerometer with default settings
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 4: Configure ACC_CONF1 (0x31) - Set high performance, 200Hz ODR
        buf[0] = BMA530_REG_ACC_CONF1;
        buf[1] = HIGH_PERFORMANCE | AVG_2_SAMPLES | ODR_200HZ;  // Set performance mode and ODR
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 5: Configure ACC_CONF2 (0x32) - Noise mode, IIR rolloff, range
        buf[0] = BMA530_REG_ACC_CONF2;
        buf[1] = NOISE_MODE_LOWER | IIR_ROLLOFF_60DB | RANGE_2G;
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 6: Configure INT1 (0x34): Edge-triggered, push-pull, active high
        buf[0] = BMA530_REG_INT1_CONFIG;
        buf[1] = 0x0B;  // Edge-triggered, push-pull, active high
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 7: Map Generic Interrupt 1 to INT1 (0x36)
        buf[0] = BMA530_REG_INT_MAP_0;
        buf[1] = 0x40;  // Map Generic Interrupt 1 to INT1
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 8: Enable Generic Interrupt 1 (0x55)
        buf[0] = BMA530_REG_FEAT_ENG_GPR_0;
        buf[1] = BMA530_ENABLE_GENERIC_INT1;
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 9: Update Feature Engine (0x54)
        buf[0] = BMA530_REG_FEAT_ENG_UPDATE;
        buf[1] = 0x01;  // Activate the feature engine
        ret = HAL_I2C_Master_Transmit(&hi2c1, (BMA530_I2C_ADDR << 1), buf, 2, HAL_MAX_DELAY);
        HAL_Delay(10);
    
        // Step 10: Configure Generic Interrupt 1
        BMA530_ConfigureGenericInt1();
    		
        snprintf(uart_buffer, sizeof(uart_buffer), "BMA530 Initialization Complete\r\n");
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    		
    		printRegisterValues();
    }
    
    void printRegisterValues(void)
    {
        uint8_t regValues[2];
    
        // Print ACC_CONF0 (0x30)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_ACC_CONF0, I2C_MEMADD_SIZE_8BIT, regValues, 1, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "ACC_CONF0 (0x30): 0x%02X\r\n", regValues[0]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print ACC_CONF1 (0x31)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_ACC_CONF1, I2C_MEMADD_SIZE_8BIT, regValues, 1, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "ACC_CONF1 (0x31): 0x%02X\r\n", regValues[0]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print ACC_CONF2 (0x32)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_ACC_CONF2, I2C_MEMADD_SIZE_8BIT, regValues, 1, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "ACC_CONF2 (0x32): 0x%02X\r\n", regValues[0]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print INT1_CONFIG (0x34)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_INT1_CONFIG, I2C_MEMADD_SIZE_8BIT, regValues, 1, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "INT1_CONFIG (0x34): 0x%02X\r\n", regValues[0]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print INT_MAP_0 (0x36)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_INT_MAP_0, I2C_MEMADD_SIZE_8BIT, regValues, 1, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "INT_MAP_0 (0x36): 0x%02X\r\n", regValues[0]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print FEAT_ENG_GPR_0 (0x55)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_FEAT_ENG_GPR_0, I2C_MEMADD_SIZE_8BIT, regValues, 1, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "FEAT_ENG_GPR_0 (0x55): 0x%02X\r\n", regValues[0]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print FEAT_ENG_UPDATE (0x54)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_FEAT_ENG_UPDATE, I2C_MEMADD_SIZE_8BIT, regValues, 1, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "FEAT_ENG_UPDATE (0x54): 0x%02X\r\n", regValues[0]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print GENERIC_INT1_1 (0x04)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_GENERIC_INT1_1, I2C_MEMADD_SIZE_8BIT, regValues, 2, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "GENERIC_INT1_1 (0x04): 0x%02X 0x%02X\r\n", regValues[0], regValues[1]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print GENERIC_INT1_2 (0x05)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_GENERIC_INT1_2, I2C_MEMADD_SIZE_8BIT, regValues, 2, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "GENERIC_INT1_2 (0x05): 0x%02X 0x%02X\r\n", regValues[0], regValues[1]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print GENERIC_INT1_3 (0x06)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_GENERIC_INT1_3, I2C_MEMADD_SIZE_8BIT, regValues, 2, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "GENERIC_INT1_3 (0x06): 0x%02X 0x%02X\r\n", regValues[0], regValues[1]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    
        // Print GENERIC_INT1_4 (0x07)
        HAL_I2C_Mem_Read(&hi2c1, (BMA530_I2C_ADDR << 1), BMA530_REG_GENERIC_INT1_4, I2C_MEMADD_SIZE_8BIT, regValues, 2, HAL_MAX_DELAY);
        snprintf(uart_buffer, sizeof(uart_buffer), "GENERIC_INT1_4 (0x07): 0x%02X 0x%02X\r\n", regValues[0], regValues[1]);
        HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);
    }

     

     This is from my header file:

     

    // Macros for register configuration
    #define HIGH_PERFORMANCE          (0x1 << 7)
    #define AVG_4_SAMPLES          		(0x2 << 4)
    #define AVG_2_SAMPLES          		(0x1 << 4)
    #define NO_AVERAGING              (0x0 << 4)
    #define ODR_200HZ                 (0x7 << 0)
    #define ODR_400HZ                 (0x8 << 0)
    #define ODR_800HZ                 (0x9 << 0)
    #define ODR_1600HZ                (0xA << 0)
    #define ODR_6400HZ                (0xC << 0)
    #define RANGE_2G                  (0x0 << 0)
    #define IIR_ROLLOFF_MINUS_40DB    (0x2 << 2)
    #define LOWER_NOISE_MODE          (0x0 << 4)
    #define IIR_ROLLOFF_MINUS_60DB  0x03
    #define NOISE_MODE_LOWER            (0x01 << 4)  // Lower noise level (default)
    #define IIR_ROLLOFF_60DB            (0x03 << 2)  // IIR filter roll-off -60dB
    
    // Register addresses
    #define BMA530_REG_CHIP_ID        0x00  // Chip ID register
    
    #define BMA530_REG_ACC_X_LSB      0x18  // LSB of X-axis acceleration data
    #define BMA530_REG_ACC_X_MSB      0x19  // MSB of X-axis acceleration data
    #define BMA530_REG_ACC_Y_LSB      0x1A  // LSB of Y-axis acceleration data
    #define BMA530_REG_ACC_Y_MSB      0x1B  // MSB of Y-axis acceleration data
    #define BMA530_REG_ACC_Z_LSB      0x1C  // LSB of Z-axis acceleration data
    #define BMA530_REG_ACC_Z_MSB      0x1D  // MSB of Z-axis acceleration data
    
    // Configuration registers
    #define BMA530_REG_ACC_CONF0     0x30  // Accelerometer configuration register 0
    #define BMA530_REG_ACC_CONF1     0x31  // Accelerometer configuration register 1 (e.g., power mode, bandwidth)
    #define BMA530_REG_ACC_CONF2     0x32  // Accelerometer configuration register 2 (e.g., noise mode, range)
    
    #define BMA530_I2C_ADDR             0x18  // I2C address for BMA530 
    
    // Motion Detection Configuration Registers
    #define BMA530_REG_GENERIC_INT1_1  0x04  // Generic Interrupt 1 Configuration register 1
    #define BMA530_REG_GENERIC_INT1_2  0x05  // Generic Interrupt 1 Configuration register 2
    #define BMA530_REG_GENERIC_INT1_3  0x06  // Generic Interrupt 1 Configuration register 3
    #define BMA530_REG_GENERIC_INT1_4  0x07  // Generic Interrupt 1 Configuration register 4
    #define BMA530_REG_INT_MAP_1       0x37  // Interrupt mapping register 1
    #define BMA530_REG_INT_MAP_2       0x38  // Interrupt mapping register 2
    #define BMA530_REG_INT1_CONFIG   	 0x34  // Register for configuring INT1 behavior
    #define BMA530_REG_FEAT_ENG_UPDATE 0x54  // Register to update the feature engine
    #define BMA530_REG_FEAT_ENG_GPR_0  0x55  // Register to enable generic interrupt 1
    
    // Macros for motion detection configurations
    #define BMA530_CONF_FEAT_ENG_ENABLE         (0x01 << 0)
    
    //For GENERIC_INT1_1
    #define BMA530_GENERIC_INT1_SLOPE_THRES(x)  ((x) & 0xFFF)
    #define BMA530_GENERIC_INT1_AXIS_SEL_X      (0x01 << 13)
    #define BMA530_GENERIC_INT1_COMB_SEL_OR     (0x00 << 12)
    
    //For GENERIC_INT1_2
    #define BMA530_GENERIC_INT1_ACC_REF_UP      (0x02 << 11) //sensor uses default reference value
    #define BMA530_GENERIC_INT1_CRITERION_SEL   (0x01 << 10) //evaluate condition for motion state of the device
    #define BMA530_GENERIC_INT1_HYSTERESIS(x)   ((x) & 0x3FF)  // 10 bits (0x3FF is 1023 in decimal)
    
    //For GENERIC_INT1_3
    #define DURATION_500MS 25  // 500 ms duration (0.5 seconds * 50), scaling factor is 50
    #define WAIT_TIME_200MS 10  // 200 ms wait time (0.2 seconds * 50), scaling factor is 50
    
    //For GENERIC_INT1_4
    #define QUIET_TIME_MIN 0  // Minimal quiet time, since it’s not needed in this application
    
    //For INT_MAP_0 register
    #define BMA530_REG_INT_MAP_0 0x36 //register address
    #define BMA530_GEN_INT1_INT_MAP_INT1 (0x01 << 6)  // Map Generic Interrupt 1 to INT1
    
    // Macro for INT1 configuration (register 0x34)
    #define INT1_CONFIG_EDGE_TRIGGERED  (0x0B)  // Edge-triggered, push-pull, active-high
    
    // Macro for updating the feature engine (register 0x54)
    #define FEATURE_ENGINE_ENABLE       (0x01)
    
    // Macro for enabling generic interrupt 1 (register 0x55)
    #define BMA530_ENABLE_GENERIC_INT1  (0x01)

     

     

    Are there any configuration steps or timing considerations I'm missing? I was able to verify the Chip ID is the expected value and accelerometer values are read correctly, so I2C is working as expected. I'm just trying to get motion detection to work so I can have the STM32 microcontroller in a low power mode and wake up when there is initial motion. 

    10 REPLIES 10

    FAE_CA1
    Community Moderator
    Community Moderator

    Hi,

    We have tried a few times by writing value of 0x09 and 0x0B to register 0x34 on our BMA530 shuttle board. BMA530 doesn't get hot. Maybe there is some kind of short in your hardware connections. Thanks.

    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