2023-08-10 05:30 AM
Hello, I am trying to use the LORA-E5 STM32WLE5JC board with the BME688 sensor, I2C connection. I used this repository as the basis GitHub - Squieler/BME68x-STM32-HAL: BME68x STM32 HAL Library, changing what was needed. But it always hangs in that role. Can anyone help me?
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) and tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) always still “reset” so brake in this part.
/* * Library Name: BME68x (I2C) - STM32 HAL and BME68x API Based Library * Written By: Ahmet Batuhan Günaltay (Great thanks to David Bird for IAQ calculation method and functions.) * Date Written: 26/05/2021 (DD/MM/YYYY) * Last Modified: 26/05/2021 (DD/MM/YYYY) * Description: This library measures temperature, humidity, pressure and IAQ with BME680x (I2C) sensors based on STM32 HAL * and BME68x API. For more information about the IAQ calculation check: https://github.com/G6EJD/BME680-Example * References: * - https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme680-ds001.pdf [Datasheet] * * Copyright (C) 2021 - Ahmet Batuhan Günaltay * (IAQ calculation substantial portion, the ideas and concepts is Copyright (c) David Bird 2018) * This software library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This software library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. * * */ /* Necessary functions for BME68x API are defined here. (Functions that are hardware dependent.) */ #include "bme68x_necessary_functions.h" // I2C handler extern I2C_HandleTypeDef hi2c2; // I2C peripheral for the device. // BME68x device address: uint8_t dev_addr = BME68X_I2C_ADDR_LOW; // High is 0x77 and low is 0x76 uint8_t chip_id = BME68X_CHIP_ID; // is 0x61 // BME68x Variables struct bme68x_dev bme; struct bme68x_data * BME68x_DATA; int8_t rslt; struct bme68x_conf conf; struct bme68x_heatr_conf heatr_conf; uint32_t del_period; uint8_t n_fields; // IAQ Calculation Variables float humidity_score, gas_score; float gas_reference = 250000; float hum_reference = 40; int8_t getgasreference_count = 0; float gas_lower_limit = 5000; // Bad air quality limit float gas_upper_limit = 50000; // Good air quality limit /* Complete init. function. */ int8_t bme68x_start(struct bme68x_data *dataPtr) { // Init. bme68x_interface_init(&bme, BME68X_I2C_INTF); // Init. for data variable BME68x_DATA = dataPtr; // Configuration /* Check if rslt == BME68X_OK, report or handle if otherwise */ conf.filter = BME68X_FILTER_OFF; conf.odr = BME68X_ODR_NONE; conf.os_hum = BME68X_OS_16X; conf.os_pres = BME68X_OS_1X; conf.os_temp = BME68X_OS_2X; bme68x_set_conf(&conf, &bme); // Heat conf. /* Check if rslt == BME68X_OK, report or handle if otherwise */ heatr_conf.enable = BME68X_ENABLE; heatr_conf.heatr_temp_prof = 320; heatr_conf.heatr_dur_prof = 150; heatr_conf.profile_len = 1; rslt = bme68x_set_heatr_conf(BME68X_SEQUENTIAL_MODE, &heatr_conf, &bme); //Gather gas reference for the IAQ calculation bme68x_GetGasReference(); return rslt; } /* Force mode measurement. */ int8_t bme68x_single_measure(struct bme68x_data *dataPtr) { bme68x_set_op_mode(BME68X_FORCED_MODE, &bme); /* Calculate delay period in microseconds */ del_period = bme68x_get_meas_dur(BME68X_FORCED_MODE, &conf, &bme) + (heatr_conf.heatr_dur * 1000); bme.delay_us(del_period, bme.intf_ptr); /* Check if rslt == BME68X_OK, report or handle if otherwise */ rslt = bme68x_get_data(BME68X_FORCED_MODE, dataPtr, &n_fields, &bme); return rslt; } /* Necessary functions. */ // I2C write function. BME68X_INTF_RET_TYPE bme68x_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; if (HAL_I2C_Mem_Write(&hi2c2, (uint16_t) (dev_addr << 1), reg_addr, 1, (uint8_t*) reg_data, len, 15) == HAL_OK) return 0; return 1; } // I2C read function. BME68X_INTF_RET_TYPE bme68x_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr) { uint8_t dev_addr = *(uint8_t*) intf_ptr; if (HAL_I2C_Mem_Read(&hi2c2, (uint16_t) ((dev_addr << 1) | 0x1), reg_addr, 1, reg_data, len, 15) == HAL_OK) return 0; return 1; } // BME68x delay function void bme68x_delay_us(uint32_t period, void *intf_ptr) { HAL_Delay(period / 1000); } // BME68x interface function int8_t bme68x_interface_init(struct bme68x_dev *bme, uint8_t intf) { int8_t rslt = BME68X_OK; if (bme != NULL) { // Check for the device on the I2C line if (HAL_I2C_IsDeviceReady(&hi2c2, (uint16_t) (dev_addr << 1), 1, 1) //stop here == HAL_OK) { // Device found at the I2C line. rslt = 0; } else { rslt = -2; // Communication error. return rslt; } /* Bus configuration : I2C */ if (intf == BME68X_I2C_INTF) { bme->read = bme68x_i2c_read; bme->write = bme68x_i2c_write; bme->intf = BME68X_I2C_INTF; } else { return -2; } bme->delay_us = bme68x_delay_us; bme->intf_ptr = &dev_addr; bme->amb_temp = 30; /* The ambient temperature in deg C is used for defining the heater temperature */ } else { rslt = BME68X_E_NULL_PTR; } return rslt; } }
HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) { uint32_t tickstart; __IO uint32_t I2C_Trials = 0UL; FlagStatus tmp1; FlagStatus tmp2; if (hi2c->State == HAL_I2C_STATE_READY) { if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) { return HAL_BUSY; } /* Process Locked */ __HAL_LOCK(hi2c); hi2c->State = HAL_I2C_STATE_BUSY; hi2c->ErrorCode = HAL_I2C_ERROR_NONE; do { /* Generate Start */ hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress); /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ /* Wait until STOPF flag is set or a NACK flag is set*/ tickstart = HAL_GetTick(); tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF); tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); while ((tmp1 == RESET) && (tmp2 == RESET)) { if (Timeout != HAL_MAX_DELAY) { if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) { /* Update I2C state */ hi2c->State = HAL_I2C_STATE_READY; /* Update I2C error code */ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_ERROR; } } tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF); tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); } /* Check if the NACKF flag has not been set */ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET) { /* Wait until STOPF flag is reset */ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) { return HAL_ERROR; } /* Clear STOP Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); /* Device is ready */ hi2c->State = HAL_I2C_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_OK; } else { /* Wait until STOPF flag is reset */ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) { return HAL_ERROR; } /* Clear NACK Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); /* Clear STOP Flag, auto generated with autoend*/ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); } /* Check if the maximum allowed number of trials has been reached */ if (I2C_Trials == Trials) { /* Generate Stop */ hi2c->Instance->CR2 |= I2C_CR2_STOP; /* Wait until STOPF flag is reset */ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) { return HAL_ERROR; } /* Clear STOP Flag */ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); } /* Increment Trials */ I2C_Trials++; } while (I2C_Trials < Trials); /* Update I2C state */ hi2c->State = HAL_I2C_STATE_READY; /* Update I2C error code */ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; /* Process Unlocked */ __HAL_UNLOCK(hi2c); return HAL_ERROR; } else { return HAL_BUSY; } }
2023-08-10 07:03 AM
If HAL_I2C_IsDeviceReady hangs for long time, your "HAL" timer is not ticking. Check why.
2023-08-11 03:38 AM
yes, it is scoring, if it beats the time it calls error function handler.