简体   繁体   English

如何调整博世传感器 API 以与 STM32 一起使用?

[英]How to adapt Bosch Sensor API's to use with STM32?

I have two Bosch sensors model BMI160 and BMP388.我有两个博世传感器 model BMI160 和 BMP388。 I am trying to use these sensors with my STM32 based NUCLEO board.我正在尝试将这些传感器与基于 STM32 的 NUCLEO 板一起使用。 I am using CubeIDE and C to code STM32.我正在使用 CubeIDE 和 C 来编写 STM32。

Bosch has APIs for its sensors and they are pretty detailed.博世为其传感器提供了 API,它们非常详细。 However, as far as I understand, a wrapper needs to be written in order to provide I2C or SPI connection.然而,据我所知,需要编写包装器才能提供 I2C 或 SPI 连接。

https://github.com/BoschSensortec/BMP3-Sensor-API https://github.com/BoschSensortec/BMP3-传感器-API

Let me give an example from BMP388.让我举一个 BMP388 的例子。 Besides the main.c and.h files of the API, there are common.c and common.h files.除了API的main.c和.h文件外,还有common.c和common.h文件。 As far as I understand interface communication happens via these files.据我了解,接口通信是通过这些文件进行的。 In the standard version, "coines" protocol is used, but I need to convert it to STM32 HAL I2C communication for both sensors.在标准版本中,使用“coines”协议,但我需要将其转换为两个传感器的 STM32 HAL I2C 通信。

For the BMP388 I created something like this:对于 BMP388,我创建了这样的东西:

BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t * reg_data, uint32_t len, void * intf_ptr);
BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr,
  const uint8_t * reg_data, uint32_t len, void * intf_ptr);

uint8_t GTXBuffer[512], GRXBuffer[2048];
int8_t SensorAPI_I2Cx_Read(uint8_t subaddress, uint8_t * pBuffer, uint32_t ReadNumbr, void * intf_ptr) {
  uint8_t dev_addr = * (uint8_t * ) intf_ptr;
  uint16_t DevAddress = dev_addr << 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 subaddress, uint8_t * pBuffer, uint32_t WriteNumbr, void * intf_ptr) {
  uint8_t dev_addr = * (uint8_t * ) intf_ptr;
  uint16_t DevAddress = dev_addr << 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;
}

But I have no idea how to edit common.c and common.h to be able to run this function.但我不知道如何编辑 common.c 和 common.h 才能运行这个 function。

Standart common.c file for BMP388, which uses COINES. BMP388 的标准 common.c 文件,它使用 COINES。

/**\
 * Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 **/

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#include "bmp3.h"
#include "coines.h"
#include "common.h"

/*! BMP3 shuttle board ID */
#define BMP3_SHUTTLE_ID  0xD3

/* Variable to store the device address */
static uint8_t dev_addr;

/*!
 * I2C read function map to COINES platform
 */
BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint8_t dev_addr = *(uint8_t*)intf_ptr;

    return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len);
}

/*!
 * I2C write function map to COINES platform
 */
BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint8_t dev_addr = *(uint8_t*)intf_ptr;

    return coines_write_i2c(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}

/*!
 * SPI read function map to COINES platform
 */
BMP3_INTF_RET_TYPE bmp3_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint8_t dev_addr = *(uint8_t*)intf_ptr;

    return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len);
}

/*!
 * SPI write function map to COINES platform
 */
BMP3_INTF_RET_TYPE bmp3_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint8_t dev_addr = *(uint8_t*)intf_ptr;

    return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}

/*!
 * Delay function map to COINES platform
 */
void bmp3_delay_us(uint32_t period, void *intf_ptr)
{
    coines_delay_usec(period);
}

void bmp3_check_rslt(const char api_name[], int8_t rslt)
{
    switch (rslt)
    {
        case BMP3_OK:

            /* Do nothing */
            break;
        case BMP3_E_NULL_PTR:
            printf("API [%s] Error [%d] : Null pointer\r\n", api_name, rslt);
            break;
        case BMP3_E_COMM_FAIL:
            printf("API [%s] Error [%d] : Communication failure\r\n", api_name, rslt);
            break;
        case BMP3_E_INVALID_LEN:
            printf("API [%s] Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
            break;
        case BMP3_E_DEV_NOT_FOUND:
            printf("API [%s] Error [%d] : Device not found\r\n", api_name, rslt);
            break;
        case BMP3_E_CONFIGURATION_ERR:
            printf("API [%s] Error [%d] : Configuration Error\r\n", api_name, rslt);
            break;
        case BMP3_W_SENSOR_NOT_ENABLED:
            printf("API [%s] Error [%d] : Warning when Sensor not enabled\r\n", api_name, rslt);
            break;
        case BMP3_W_INVALID_FIFO_REQ_FRAME_CNT:
            printf("API [%s] Error [%d] : Warning when Fifo watermark level is not in limit\r\n", api_name, rslt);
            break;
        default:
            printf("API [%s] Error [%d] : Unknown error code\r\n", api_name, rslt);
            break;
    }
}

BMP3_INTF_RET_TYPE bmp3_interface_init(struct bmp3_dev *bmp3, uint8_t intf)
{
    int8_t rslt = BMP3_OK;
    struct coines_board_info board_info;

    if (bmp3 != NULL)
    {
        int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB);
        if (result < COINES_SUCCESS)
        {
            printf(
                "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n"
                " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n");
            exit(result);
        }

        result = coines_get_board_info(&board_info);

#if defined(PC)
        setbuf(stdout, NULL);
#endif

        if (result == COINES_SUCCESS)
        {
            if ((board_info.shuttle_id != BMP3_SHUTTLE_ID))
            {
                printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n");
                exit(COINES_E_FAILURE);
            }
        }

        coines_set_shuttleboard_vdd_vddio_config(0, 0);
        coines_delay_msec(1000);

        /* Bus configuration : I2C */
        if (intf == BMP3_I2C_INTF)
        {
            printf("I2C Interface\n");
            dev_addr = BMP3_ADDR_I2C_PRIM;
            bmp3->read = bmp3_i2c_read;
            bmp3->write = bmp3_i2c_write;
            bmp3->intf = BMP3_I2C_INTF;
            coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
        }
        /* Bus configuration : SPI */
        else if (intf == BMP3_SPI_INTF)
        {
            printf("SPI Interface\n");
            dev_addr = COINES_SHUTTLE_PIN_7;
            bmp3->read = bmp3_spi_read;
            bmp3->write = bmp3_spi_write;
            bmp3->intf = BMP3_SPI_INTF;
            coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
        }

        coines_delay_msec(1000);

        coines_set_shuttleboard_vdd_vddio_config(3300, 3300);

        coines_delay_msec(1000);

        bmp3->delay_us = bmp3_delay_us;
        bmp3->intf_ptr = &dev_addr;
    }
    else
    {
        rslt = BMP3_E_NULL_PTR;
    }

    return rslt;
}

void bmp3_coines_deinit(void)
{
    fflush(stdout);

    coines_set_shuttleboard_vdd_vddio_config(0, 0);
    coines_delay_msec(1000);

    /* Coines interface reset */
    coines_soft_reset();
    coines_delay_msec(1000);
    coines_close_comm_intf(COINES_COMM_INTF_USB);
}

it should be sufficient to substitute the coin functions with the ones you wrote.将硬币函数替换为您编写的函数应该就足够了。

For instance:例如:

Substitute:代替:

return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len);

with:和:

SensorAPI_I2Cx_Read(dev_addr, reg_addr, reg_data, (uint16_t)len)

you then just need to check that the calls are compatible types然后你只需要检查调用是否兼容类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM