Bosch Sensortec Community

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

    BHI160b Shuttle Board with STM32

    BHI160b Shuttle Board with STM32

    belaya
    Established Member

    Hi,

    i am trying to read quaternion's out of the BHI160b, that's why i purchased the BHI160b shuttle Board from Bosch. I want to connect it with my NUCLEO-F411RE from STM. So i implemented the library into my STM project. The next step was to figure out how to use the HAL_I2C functions to communicate with the sensor. I changed the read/write operations in the driver's file bhy_support.c like this:

    uint8_t GTXBuffer[256];
    
    int8_t SensorAPI_I2Cx_Read(uint8_t slave_address7, uint8_t subaddress, uint8_t *pBuffer, uint16_t ReadNumbr)
    {
    uint16_t DevAddress = slave_address7 << 1;
    
    // send register address
    HAL_I2C_Master_Transmit(&I2C_HANDLE, DevAddress, &subaddress, 1, BUS_TIMEOUT);
    HAL_I2C_Master_Receive(&I2C_HANDLE, DevAddress, pBuffer, ReadNumbr, BUS_TIMEOUT);
    return 0;
    }
    
    int8_t SensorAPI_I2Cx_Write(uint8_t slave_address7, uint8_t subaddress, uint8_t *pBuffer, uint16_t WriteNumbr)
    {
    uint16_t DevAddress = slave_address7 << 1;
    
    GTXBuffer[0] = subaddress;
    memcpy(&GTXBuffer[1], pBuffer, WriteNumbr);
    
    // send register address
    HAL_I2C_Master_Transmit(&I2C_HANDLE, DevAddress, GTXBuffer, WriteNumbr+1, BUS_TIMEOUT);
    return 0;
    }

    I connected the Shuttle Board to my NUCLEO board like this:

    ShuttleBoard Connector.png

    ___J1___|___NUCLEO___
       1/2  |    3.3V
        3   |    GND
       17   |    PB7 -> I2C1_SCL
       18   |    PB6 -> I2C1_SDA 
       21   |    PB5 -> DI/BHI160_INT

    In my main loop i startet to initialize BHI160 Sensor with the function bhy_initialize_support();:

    int main(void)
    {
      /* MCU Configuration--------------------------------------------------------*/
    
      HAL_Init();
      SystemClock_Config();
      MX_GPIO_Init();
      MX_I2C1_Init();
    
      /* USER CODE BEGIN 2 */
    
      bhy_initialize_support();
    
      /* USER CODE END 2 */
    
      while (1)
      {
                /* USER CODE END WHILE */
    	  int8_t ret;
    
    	      /* BHY Variable*/
    	      uint8_t                    *fifoptr           = NULL;
    	      uint8_t                    bytes_left_in_fifo = 0;
    	      uint16_t                   bytes_remaining    = 0;
    	      uint16_t                   bytes_read         = 0;
    	      bhy_data_generic_t         fifo_packet;
    	      bhy_data_type_t            packet_type;
    	      BHY_RETURN_FUNCTION_TYPE   result;
    
    	      /* the remapping matrix for BHA or BHI here should be configured according to its placement on customer's PCB. */
    	      /* for details, please check 'Application Notes Axes remapping of BHA250(B)/BHI160(B)' document. */
    	      int8_t                     bhy_mapping_matrix_config[3*3] = {0,1,0,-1,0,0,0,0,1};
    	      /* the remapping matrix for Magnetometer should be configured according to its placement on customer's PCB.  */
    	      /* for details, please check 'Application Notes Axes remapping of BHA250(B)/BHI160(B)' document. */
    	      int8_t                     mag_mapping_matrix_config[3*3] = {0,1,0,1,0,0,0,0,-1};
    	      /* the sic matrix should be calculated for customer platform by logging uncalibrated magnetometer data. */
    	      /* the sic matrix here is only an example array (identity matrix). Customer should generate their own matrix. */
    	      /* This affects magnetometer fusion performance. */
    	      float sic_array[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
    
    		/* To get the customized version number in firmware, it is necessary to read Parameter Page 2, index 125 */
    	    /* to get this information. This feature is only supported for customized firmware. To get this customized */
    	    /* firmware, you need to contact your local FAE of Bosch Sensortec. */
    	    //struct cus_version_t      bhy_cus_version;
    
    		while (HAL_GPIO_ReadPin(BHI160_INT_GPIO_Port, BHI160_INT_Pin) == GPIO_PIN_RESET);
    	    /* init the bhy chip */
    	    if(bhy_driver_init(&bhy1_fw))
    	    {
    	        //DEBUG("Fail to init bhy\n");
    	    }
    
    	    /* wait for the bhy trigger the interrupt pin go down and up again */
    
    		//while (HAL_GPIO_ReadPin(BHI160_INT_GPIO_Port, BHI160_INT_Pin) == GPIO_PIN_SET);
    
    	    HAL_Delay(100);
    
    		while (HAL_GPIO_ReadPin(BHI160_INT_GPIO_Port, BHI160_INT_Pin) == GPIO_PIN_RESET);
    
    	    /* To get the customized version number in firmware, it is necessary to read Parameter Page 2, index 125 */
    	    /* to get this information. This feature is only supported for customized firmware. To get this customized */
    	    /* firmware, you need to contact your local FAE of Bosch Sensortec. */
    	    //bhy_read_parameter_page(BHY_PAGE_2, PAGE2_CUS_FIRMWARE_VERSION, (uint8_t*)&bhy_cus_version, sizeof(struct cus_version_t));
    	    //DEBUG("cus version base:%d major:%d minor:%d\n", bhy_cus_version.base, bhy_cus_version.major, bhy_cus_version.minor);
    
    	    /* the remapping matrix for BHI and Magmetometer should be configured here to make sure rotation vector is */
    	    /* calculated in a correct coordinates system. */
    	    bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_ACC, bhy_mapping_matrix_config);
    	    bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_MAG, mag_mapping_matrix_config);
    	    bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_GYRO, bhy_mapping_matrix_config);
    	    /* This sic matrix setting affects magnetometer fusion performance. */
    	    bhy_set_sic_matrix(sic_array);
    
    	    /* install the callback function for parse fifo data */
    	    if(bhy_install_sensor_callback(VS_TYPE_ROTATION_VECTOR, VS_WAKEUP, sensors_callback_rotation_vector))
    	    {
    	        //DEBUG("Fail to install sensor callback\n");
    	    }
    
    	    /* enables the virtual sensor */
    	    if(bhy_enable_virtual_sensor(VS_TYPE_ROTATION_VECTOR, VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0))
    	    {
    	        //DEBUG("Fail to enable sensor id=%d\n", VS_TYPE_ROTATION_VECTOR);
    	    }
    
    
    
    	    /* continuously read and parse the fifo */
    	    while (1)
    	    {
    
    	        /* wait until the interrupt fires */
    	        /* unless we already know there are bytes remaining in the fifo */
    	        while (!HAL_GPIO_ReadPin(BHI160_INT_GPIO_Port, BHI160_INT_Pin) && !bytes_remaining)
    	        {
    	        }
    
    	        bhy_read_fifo(fifo + bytes_left_in_fifo, FIFO_SIZE - bytes_left_in_fifo, &bytes_read, &bytes_remaining);
    	        bytes_read           += bytes_left_in_fifo;
    	        fifoptr              = fifo;
    	        packet_type          = BHY_DATA_TYPE_PADDING;
    
    
    	        do
    	        {
    	            /* this function will call callbacks that are registered */
    	            result = bhy_parse_next_fifo_packet(&fifoptr, &bytes_read, &fifo_packet, &packet_type);
    
    	            /* prints all the debug packets */
    	            if (packet_type == BHY_DATA_TYPE_DEBUG)
    	            {
    	                bhy_print_debug_packet(&fifo_packet.data_debug, bhy_printf);
    	            }
    
    	            /* the logic here is that if doing a partial parsing of the fifo, then we should not parse  */
    	            /* the last 18 bytes (max length of a packet) so that we don't try to parse an incomplete   */
    	            /* packet */
    	        } while ((result == BHY_SUCCESS) && (bytes_read > (bytes_remaining ? MAX_PACKET_LENGTH : 0)));
    
    	        bytes_left_in_fifo = 0;
    
    	        if (bytes_remaining)
    	        {
    	            /* shifts the remaining bytes to the beginning of the buffer */
    	            while (bytes_left_in_fifo < bytes_read)
    	            {
    	                fifo[bytes_left_in_fifo++] = *(fifoptr++);
    	            }
    	        }
    	    }
    
        /* USER CODE BEGIN 3 */
        }
    }

    When my programm jumps into the function it checks the product_id of the sensor and returns * return BHY_SUCCESS;* which means that the I2C connection is working!

    Bosch also provides some example code for different sensor readings here. Because i want my rotation data in quaternion's i looked at the rotation_vector_example.c example. There are two functions static void sensors_callback_rotation_vector() and void demo_sensor(), but i cant get this code to work. I put the demo_sensor() in to my main loop and have the Sensor_callback_rotation_vector()  in my main.c file. Maybe there is an other way to use this driver? In the documentation they say that the driver helps you in 3 phases to read out data: initialization, configuration and data readout. But i cant figure out how to actually do it!

    22 REPLIES 22

    belaya
    Established Member

    Bevor i checked the bhy_enable_virtual_sensor i checked this line before.

    	    if(bhy_install_sensor_callback(VS_TYPE_ROTATION_VECTOR, VS_WAKEUP, sensors_callback_rotation_vector))
    	    {
    	        //DEBUG("Fail to install sensor callback\n");
    	    }

    I placed 4 Breakpoints on the return values like this.

    install_Sensor_callback.png

    So the return value after bhy_install_sensor_callback is BHY_SUCCESS.

    After i installed the callback i want to enable the virtual sensor like this.

    	    if(bhy_enable_virtual_sensor(VS_TYPE_ROTATION_VECTOR, VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0))
    	    {
    	        //DEBUG("Fail to enable sensor id=%d\n", VS_TYPE_ROTATION_VECTOR);
    	    }

    In the Debug session i jumped into this function and checked its return value.

    enable_virtual_sensor.png

    The return value is 18.

    I tried to implement also the meta event callback. For that i have some questions.

    Can i implement more that one callback function on the sensor?

    If yes, i implemented the function after the sensor Install and callback. Is this working like that?

    	    /* install the meta event callback */
    	    if(bhy_install_meta_event_callback())
    	    {
    	        //DEBUG("Fail to enable sensor id=%d\n", VS_TYPE_ROTATION_VECTOR);
    	    }

    I am not sure which BHY_META_EVENT i have to install to get the current sensor status. I checked the selftest_example in the git repository.

    They installed the meta event callback like this:

        bhy_install_meta_event_callback(BHY_META_EVENT_TYPE_INITIALIZED, meta_event_callback);
        bhy_install_meta_event_callback(BHY_META_EVENT_TYPE_SELF_TEST_RESULTS, meta_event_callback);

    but none of these callbacks gives me the current sensor status? So which one do i have to use?

    Vincent
    Community Moderator
    Community Moderator

    what is the value for following parameter in your code? 

    ROTATION_VECTOR_SAMPLE_RATE

     It shows a enable sensor error (expect return value is also 0 for this funciton).  then you don't really enable any virtual sensor, so no data in FIFO,  no interrupt fired. 

    Enable virtual sensor is just mapping the settings into coresponding register content, then do a burst write into sensor. 

    Following are the error code we defined in the BHY driver.  you got -18 (all error is minus).  so you should have several write parameter pages error in calling our API code. 

    Thus,  i ask to check both sample rate and your write function again. 

    If you have logic analyzer plotter is better to understanding the issue.

    #define BHY_NULL_PTR ((void *) 0)
    #define BHY_NULL ((u8)0)
    #define BHY_COMM_RES ((s8)-1)
    #define BHY_OUT_OF_RANGE ((s8)-2)
    #define BHY_SUCCESS ((u8)0)
    #define BHY_ERROR ((s8)-3)

    Vincent
    Community Moderator
    Community Moderator

    According to the meta event,  i want the following meta event type to be checked:

    BHY_META_EVENT_TYPE_ERROR = 4,
    BHY_META_EVENT_TYPE_SENSOR_ERROR = 11,

    Or you can try to print the content with meta event id in the FIFO for reference. 

    belaya
    Established Member

    Thats how i defined the sample rate in main.c

    #define ROTATION_VECTOR_SAMPLE_RATE    100

    It seems like that my read and write function is not working properly. I refered to the code from a different topic. But i dont know how he initialized the I2C interface. That how i did it:

      hi2c1.Instance = I2C1;
      hi2c1.Init.ClockSpeed = 100000;
      hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
      hi2c1.Init.OwnAddress1 = 0;
      hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
      hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
      hi2c1.Init.OwnAddress2 = 0;
      hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
      hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
      if (HAL_I2C_Init(&hi2c1) != HAL_OK)
      {
        Error_Handler();
      }

    Actually i also dont know how long i should set my delay on the i2c transmit/receive function...

    Vincent
    Community Moderator
    Community Moderator

    The interface initialize looks OK from my side.

    And i found one thing in your HW connection:  J1 pin 17 is SDA.  in your previous conent,  you connect it to SCL.

    If the FW download is successfully,  actually i will expect a good write function of the platform.

    Can you check exactly which function got error code returned then we can know exactly which step you got issue? 

    If possible,  you can just put your logic analyzer data log and shared to us for double check.

    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