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

    Thank you for your reply. I recorded the i2c connection with my logic analyzer.

    i2c.png

     This is everything i could capture after a reset on my NUCLEO Board. When i try to read from the Sensor i get an NAK. Maybe the read function doesn work?

    belaya
    Established Member

    After i changed the read and write function from

    // send register address
    HAL_I2C_Master_Transmit(&hi2c1, DevAddress, &subaddress, 1, 1);
    HAL_I2C_Master_Receive(&hi2c1, DevAddress, pBuffer, ReadNumbr, 1);

    to

    // send register address
    HAL_I2C_Master_Transmit(&hi2c1, DevAddress, &subaddress, 1, HAL_MAX_DELAY);
    HAL_I2C_Master_Receive(&hi2c1, DevAddress, pBuffer, ReadNumbr, HAL_MAX_DELAY);

    the i2c capture looks like this.

    i2c2.png

     


    Vincent
    Community Moderator
    Community Moderator

    What is your current result?

    From the plotter, i can see the INT pins goes to high after download the FW.  So look like you got successful download of FW. 

    What is the current status for bhy_driver_init function?

    belaya
    Established Member

    Right now my code wait until the interrupt fires to read and parse the fifo. But the Interrupt changes just one time after the fw download.

    The Result of  the function bhy_driver_init function is 0 as you can see in the screenshot.

    init_result.png

    Vincent
    Community Moderator
    Community Moderator

    OK,  it is good news that the driver init is successfully. 

    Now you stuck at enable virtual sensor. 

    Can you check the return value of the following function?

    bhy_enable_virtual_sensor

     Can you also add the meta event call back to read out the sensor status?  This can help us to understand your current issue and where you stucked.

    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