/**************************************************************************** * * \section Disclaimer * * Common: * Bosch Sensortec products are developed for the consumer goods industry. * They may only be used within the parameters of the respective valid * product data sheet. Bosch Sensortec products are provided with the * express understanding that there is no warranty of fitness for a * particular purpose.They are not fit for use in life-sustaining, * safety or security sensitive systems or any system or device * that may lead to bodily harm or property damage if the system * or device malfunctions. In addition,Bosch Sensortec products are * not fit for use in products which interact with motor vehicle systems. * The resale and or use of products are at the purchasers own risk and * his own responsibility. The examination of fitness for the intended use * is the sole responsibility of the Purchaser. * * The purchaser shall indemnify Bosch Sensortec from all third party * claims, including any claims for incidental, or consequential damages, * arising from any product use not covered by the parameters of * the respective valid product data sheet or not approved by * Bosch Sensortec and reimburse Bosch Sensortec for all costs in * connection with such claims. * * The purchaser must monitor the market for the purchased products, * particularly with regard to product safety and inform Bosch Sensortec * without delay of all security relevant incidents. * * Engineering Samples are marked with an asterisk (*) or (e). * Samples may vary from the valid technical specifications of the product * series. They are therefore not intended or fit for resale to third * parties or for use in end products. Their sole purpose is internal * client testing. The testing of an engineering sample may in no way * replace the testing of a product series. Bosch Sensortec assumes * no liability for the use of engineering samples. * By accepting the engineering samples, the Purchaser agrees to indemnify * Bosch Sensortec from all claims arising from the use of engineering * samples. * * Special: * This software module (hereinafter called "Software") and any information * on application-sheets (hereinafter called "Information") is provided * free of charge for the sole purpose to support your application work. * The Software and Information is subject to the following * terms and conditions: * * The Software is specifically designed for the exclusive use for * Bosch Sensortec products by personnel who have special experience * and training. Do not use this Software if you do not have the * proper experience or training. * * This Software package is provided `` as is `` and without any expressed * or implied warranties,including without limitation, the implied warranties * of merchantability and fitness for a particular purpose. * * Bosch Sensortec and their representatives and agents deny any liability * for the functional impairment * of this Software in terms of fitness, performance and safety. * Bosch Sensortec and their representatives and agents shall not be liable * for any direct or indirect damages or injury, except as * otherwise stipulated in mandatory applicable law. * * The Information provided is believed to be accurate and reliable. * Bosch Sensortec assumes no responsibility for the consequences of use * of such Information nor for any infringement of patents or * other rights of third parties which may result from its use. * No license is granted by implication or otherwise under any patent or * patent rights of Bosch. Specifications mentioned in the Information are * subject to change without notice. **************************************************************************/ #include "bme680_bsec_task.h" #ifdef BME680_BSEC_SENSOR #include ".\BSEC_1.4.7.4\bsec_integration.h" #include ".\BSEC_1.4.7.4\config\generic_33v_3s_4d\bsec_serialized_configurations_iaq.h" #define I2C_ADDRESS BME680_I2C_ADDR_PRIMARY extern volatile uint8_t int0_flag; extern volatile uint8_t int1_flag; #ifdef SUPPORT_I2C int8_t BST_sensor_i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len) { return SensorAPI_I2Cx_Read(dev_addr, reg_addr, data, len); } int8_t BST_sensor_i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len) { return SensorAPI_I2Cx_Write(dev_addr, reg_addr, data, len); } #endif #ifdef SUPPORT_SPI int8_t BST_sensor_spi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len) { // reg_addr |=0x80; return SensorAPI_SPIx_Read(dev_addr, reg_addr, data, len); } int8_t BST_sensor_spi_write(uint8_t dev_addr,uint8_t reg_addr, uint8_t *data, uint16_t len) { // reg_addr &=0x7f; // HAL_Delay(1); return SensorAPI_SPIx_Write(dev_addr, reg_addr, data, len); } #endif void bme680_communication_config(struct bme680_dev *dev) { /* Modify the parameters */ #ifdef SUPPORT_SPI dev->dev_id = 0; dev->intf = BME680_SPI_INTF; #else dev->dev_id = I2C_ADDRESS << 1; dev->intf = BME680_I2C_INTF; #endif return; } uint8_t b10msCnt=0; uint8_t b100msCnt=0; #define Time10MSCNT 10 #define Time100MSCNT 100 uint16_t bTim3_3sCnt=0; #define Time3_3sCNT 2000 /**********************************************************************************************************************/ /* functions */ /**********************************************************************************************************************/ /*! * @brief Write operation in either I2C or SPI * * param[in] dev_addr I2C or SPI device address * param[in] reg_addr register address * param[in] reg_data_ptr pointer to the data to be written * param[in] data_len number of bytes to be written * * @return result of the bus communication function */ int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) { // ... // Please insert system specific function to write to the bus where BME680 is connected // ... #ifdef SUPPORT_I2C SensorAPI_I2Cx_Write(dev_addr,reg_addr,reg_data_ptr,data_len); #endif #ifdef SUPPORT_SPI BST_sensor_spi_write(dev_addr,reg_addr,reg_data_ptr,data_len); #endif return 0; } /*! * @brief Read operation in either I2C or SPI * * param[in] dev_addr I2C or SPI device address * param[in] reg_addr register address * param[out] reg_data_ptr pointer to the memory to be used to store the read data * param[in] data_len number of bytes to be read * * @return result of the bus communication function */ int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) { // ... // Please insert system specific function to read from bus where BME680 is connected // ... #ifdef SUPPORT_I2C BST_sensor_i2c_read(dev_addr,reg_addr,reg_data_ptr,data_len); #endif #ifdef SUPPORT_SPI BST_sensor_spi_read(dev_addr,reg_addr,reg_data_ptr,data_len); #endif return 0; } /*! * @brief System specific implementation of sleep function * * @param[in] t_ms time in milliseconds * * @return none */ void sleep(uint32_t t_ms) { // ... // Please insert system specific function sleep or delay for t_ms milliseconds // ... HAL_Delay(t_ms); } /*! * @brief Capture the system time in microseconds * * @return system_current_time current system timestamp in microseconds */ int64_t get_timestamp_us() { int64_t system_current_time = 0; // ... // Please insert system specific function to retrieve a timestamp (in microseconds) // ... system_current_time =(int64_t)(HAL_GetTick()*1000); return system_current_time; } /*! * @brief Handling of the ready outputs * * @param[in] timestamp time in nanoseconds * @param[in] iaq IAQ signal * @param[in] iaq_accuracy accuracy of IAQ signal * @param[in] temperature temperature signal * @param[in] humidity humidity signal * @param[in] pressure pressure signal * @param[in] raw_temperature raw temperature signal * @param[in] raw_humidity raw humidity signal * @param[in] gas raw gas sensor signal * @param[in] bsec_status value returned by the bsec_do_steps() call * * @return none */ void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity, float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status, float static_iaq, float co2_equivalent, float breath_voc_equivalent) { // ... // Please insert system specific code to further process or display the BSEC outputs // ... // PDEBUG("bsec_status: %d\n",bsec_status); if (bsec_status == BSEC_OK) { // PDEBUG("Timestamp(ns): %d, iaq:%.3f, iaq_accuracy:%d, temp:%.3f, hum:%.3f, pres:%.3f, raw temp:%.3f, raw hum:%.3f, gas:%.3f\n",(int32_t)(timestamp/1000000),iaq,iaq_accuracy,temperature,humidity,pressure,raw_temperature,raw_humidity,gas); PDEBUG("# timestamp = %d, iaq = %.3f, iaq_accuracy = %d, temperature=%.3f, humidity=%.3f, pressure=%.3f, bsec_status =%d\r\n", (int32_t)(timestamp/1000000),iaq,iaq_accuracy,temperature,humidity, pressure,bsec_status); // PDEBUG("# raw_temperature = %.3f, raw_humidity=%.3f, gas=%.3f\r\n",raw_temperature,raw_humidity,gas); PDEBUG("# co2_equivalent=%.3f, breath_voc_equivalent=%.3f, static_iaq=%.3f\r\n",co2_equivalent, breath_voc_equivalent,static_iaq); // PDEBUG("*********************************************************************************************************************************\r\n"); } } /*! * @brief Load previous library state from non-volatile memory * * @param[in,out] state_buffer buffer to hold the loaded state string * @param[in] n_buffer size of the allocated state buffer * * @return number of bytes copied to state_buffer */ uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer) { // ... // Load a previous library state from non-volatile memory, if available. // // Return zero if loading was unsuccessful or no state was available, // otherwise return length of loaded state string. // ... return 0; } /*! * @brief Save library state to non-volatile memory * * @param[in] state_buffer buffer holding the state to be stored * @param[in] length length of the state string to be stored * * @return none */ void state_save(const uint8_t *state_buffer, uint32_t length) { // ... // Save the string some form of non-volatile memory, if possible. // ... PDEBUG("state_save length = %d\r\n",length); } /*! * @brief Load library config from non-volatile memory * * @param[in,out] config_buffer buffer to hold the loaded state string * @param[in] n_buffer size of the allocated state buffer * * @return number of bytes copied to config_buffer */ uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer) { // ... // Load a library config from non-volatile memory, if available. // // Return zero if loading was unsuccessful or no config was available, // otherwise return length of loaded config string. // ... memcpy(config_buffer, bsec_config_iaq, sizeof(bsec_config_iaq)); return sizeof(bsec_config_iaq); // return 0; } int BME680_BSEC_MODULE_RUN(void) { return_values_init ret; /* Call to the function which initializes the BSEC library * Switch on low-power mode and provide no temperature offset */ ret = bsec_iot_init(BSEC_SAMPLE_RATE_LP, 0.0f, bus_write, bus_read, sleep, state_load, config_load); PDEBUG("bsec_iot_init =%d,%d\r\n",ret.bme680_status,ret.bsec_status); if (ret.bme680_status) { /* Could not intialize BME680 */ return (int)ret.bme680_status; } else if (ret.bsec_status) { /* Could not intialize BSEC library */ return (int)ret.bsec_status; } /* Call to endless loop function which reads and processes data based on sensor settings */ /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes */ // bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 10000); return 0; } #if 1 void vGetBme680IAQ(void) { return_values_init ret; int stats; ret = bsec_iot_init(BSEC_SAMPLE_RATE_LP, 0.0f, bus_write, bus_read, sleep, state_load, config_load); if (ret.bme680_status) { /* Could not intialize BME680 */ PDEBUG("ret.bme680_status:%d \r\n",(int)ret.bme680_status); } else if (ret.bsec_status) { /* Could not intialize BSEC library */ PDEBUG("ret.bsec_status:%d \r\n",(int)ret.bsec_status); } bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 10000); } #endif void StartBstTask(void const * argument) { PDEBUG("\n"); PDEBUG("***************Enter BME680_BSEC StartBstTask()!************************\r\n"); PDEBUG("\n"); #ifdef SUPPORT_SPI BMA_SPI_MODE_CONFIG(); #endif HAL_Delay(1); // BMI4XX_REG_READ(0x50,1); //SPI // BMI4XX_REG_READ(0xD0,1);//i2c vGetBme680IAQ(); // BME680_BSEC_MODULE_RUN(); PDEBUG("Enter BME680_BSEC Task Loop!\r\n"); for(;;) { osDelay(1); } } #endif