Bosch Sensortec Community

    Showing results for 
    Search instead for 
    Did you mean: 

    BMA400 tap interrupt does not appear in interrupt status register

    BMA400 tap interrupt does not appear in interrupt status register

    New Poster


    So far I have successfully rewritten my code to use the BMA400. I am using the I2C interface and both interrupt lines.

    On INT1 the single tap and orientation interrupts are active.
    On INT2 the data ready interrupt is active.

    On INT1 line I get proper signals to signal the interrupt. When I read the status register (0x03) it shows 0x95 meaning there is an interrupt active.
    When reading the interrupt status registers (0x0E, 0x0X,0x10) I only get proper reading for the orientation interrupt (0x02,0x00,0x00). When a tap occurs it signals the interrupt, but there is no bit active in any of the interrupt status registers. I would expect (0x00,0x04,0x00) for single tap but am getting only zeros.

    I confirmed that the I2C interface works well for single byte read and multi byte read.

    Is there something in my setup that is wrong?

        accError += BMA400_WriteRegister( BMA400_REG_ACCEL_CONFIG_0, BMA400_MODE_NORMAL );
        // BMA400 needs approx 1500us to switch from sleep to normal mode
        //---- CONFIG1 ----
        // OSR = 00, BMA400_ACCEL_OSR_SETTING_0
        // ODR = 200 Hz, BMA400_ODR_200HZ
        // BMA400_RANGE_2G
        //---- CONFIG2 ----
        // src data reg = BMA400_DATA_SRC_ACCEL_FILT_1 (variable ODR)
        values[0] = (BMA400_ODR_200HZ                                    ) | \
                    (BMA400_ACCEL_OSR_SETTING_0 << BMA400_OSR_POS        ) | \
                    (BMA400_RANGE_2G            << BMA400_ACCEL_RANGE_POS);
        values[1] = (BMA400_DATA_SRC_ACCEL_FILT_LP << BMA400_DATA_FILTER_POS);      //todo debug code??
        accError += BMA400_BurstWrite( BMA400_REG_ACCEL_CONFIG_1, values, 2 );
        CC_LOGD("REG_ACCEL_CONF          (%u) 0x%02x 0x%02x 0x%02x", BMA400_BurstRead( BMA400_REG_ACCEL_CONFIG_0, values, 3), values[0], values[1], values[2] );
        //--- tap config ----
        values[0] = (BMA400_TAP_X_AXIS_EN       << BMA400_TAP_AXES_EN_POS) | \
                    (BMA400_TAP_SENSITIVITY_3                              );
        values[1] = 0x06;
        accError += BMA400_BurstWrite( BMA400_REG_TAP_CONFIG, values, 2 );
        CC_LOGD("REG_TAP_CONFIG          (%u) 0x%02x 0x%02x", BMA400_BurstRead( BMA400_REG_TAP_CONFIG, values, 2), values[0], values[1], values[2] );
        //---- tilt config ----
        values[0] = 0xC0 | 0x10 | 0x0C ;    // z/y-axis, src=LP-filtered, auto-update from LP-filtered
        values[1] = 0x06;                   // orient threshold, LSB = 8 mg
        values[2] = 0x00;                   // stability threshold - unused
        values[3] = 0x32;                   // duration until int, multiple of src ticks (filt_LP = 100Hz => 10ms)
        accError += BMA400_BurstWrite( BMA400_REG_ORIENTCH_INT_CONFIG, values, 4);
        CC_LOGD("REG_ORIENTCH_INT_CONFIG (%u) 0x%02x 0x%02x 0x%02x 0x%02x", BMA400_BurstRead( BMA400_REG_ORIENTCH_INT_CONFIG, values, 4), values[0], values[1], values[2], values[3] );
        //---- FIFO config BMA400_REG_FIFO_CONFIG_0 ----
        values[0] = BMA400_FIFO_EN_XYZ << BMA400_FIFO_AXES_EN_POS;  // x/y/z-axis enabled, streaming mode, no-flush, 12bit-mode
        values[1] = 0x00;                   // FIFO watermark = 0
        values[2] = 0x00;                   // FIFO watermark = 0
        values[3] = 0x00;                   // FIFO read enabled
        accError += BMA400_BurstWrite( BMA400_REG_FIFO_CONFIG_0, values, 4);
        CC_LOGD("REG_FIFO_CONFIG         (%u) 0x%02x 0x%02x 0x%02x 0x%02x", BMA400_BurstRead( BMA400_REG_FIFO_CONFIG_0, values, 4), values[0], values[1], values[2], values[3] );
        //---- interrupt config ----
        //disable all interrupts before configuring them
        //read them
        CC_LOGD("REG_INT_CONF (before)   (%u) 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", BMA400_BurstRead( BMA400_REG_INT_CONF_0, values, 6), values[0], values[1], values[2], values[3], values[4] );
        values[0] = BMA400_EN_ORIENT_CH_MSK | BMA400_EN_DRDY_MSK;// INT_CONF_0: enable orientation change and data-ready
        values[1] = BMA400_EN_S_TAP_MSK;    // INT_CONF_1: enable S-Tap     
        values[2] = BMA400_EN_ORIENT_CH_MSK;// INT1_MAP  : map orientation to Int1
        values[3] = BMA400_EN_DRDY_MSK;     // INT2_MAP  : map data-ready to Int2
        values[4] = BMA400_EN_S_TAP_MSK;    // INT12_MAP : map S-Tap to Int1
        values[5] = 0x00;                   // INT12_IO_CTRL: push-pull, low-active
        accError += BMA400_BurstWrite( BMA400_REG_INT_CONF_0, values, 6);
        CC_LOGD("REG_INT_CONF            (%u) 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", BMA400_BurstRead( BMA400_REG_INT_CONF_0, values, 6), values[0], values[1], values[2], values[3], values[4], values[5] );
        // check status of device after config
        BMA400_ReadRegister( BMA400_REG_STATUS, &value);
        CC_LOGD("Status: %u", value);


    Also is there something I am missing about interrupt behaviour of tap/double tap interrupt maybe?
    I read the document: "How to generate BMA400 single-tap and double-tap interrupt.pdf" and found the notice: 
    "The single-tap interrupt will be cleared automatically when the above conditions [sope and timing] are no longer valid."
    This does not mean that the interrupt flags in the interrupt status are cleared, correct?

    Thanks for any pointers!

    3 REPLIES 3

    Community Moderator
    Community Moderator


    I finally got this project back on the desk.

    The code of configuring the BMA400 works very well and interrupt handling on the MCU works fine, too.
    So my question remains:
    Does the tap interrupt get cleared by the BMA400 interrupt engine in INT_STATx, once some other acceleration data has been evaluated by the tap detection algorithm which led to no tap event?

    Also I am observing that:

    • no tap events are visible in INT_STATx when data ready interrupt is enabled. If data ready gets disabled, I suddenly start seeing tap events.
    • data ready interrupt is never visible as flag in INT_STATx, only in the STATUS register - is that expected behaviour?

    So I am wondering how exactly the interrupt engine works in order to setup as my application needs.
    Any documents or experience on this?

    Thanks a lot!

    Community Moderator
    Community Moderator


    BMA400 interrupts are in non-latched mode by default. This means that when the interrupt condition is true, interrupt will be generated. If the interrupt is mapped to INT1 pin or INT2 pin, then you will see a pulse on that pin. After a certain amount of time, the interrupt will be cleared by itself. The corresponding bit to the interrupt in INT_STATx registers is identital to interrupt signal on INT1 or INT2 pin. This means that when interrupt signal is cleared, the corresponding bit in INT_STATx will be cleared as well. If you are lucky enough you may read that bit from INT_STATx register with value of "1".

    Data ready interrupt is described in BMA400 datasheet as shown below. If you want to get data ready interrupt bit with value of "1" from INT_STATx registers, then you can write value of 0x8C to register 0x20 in the sample pseudo code to latch the interrupt. After you read INT_STATx registers all the corresponding interrupt bits will be cleared.


    If you want to read tap interrupt bits from INT_STATx registers, you can do the same thing by writing the value of 0x8C to register 0x20 to latch the interrupts.