stmicroelectronics / stm32wlxx_hal_driver Goto Github PK
View Code? Open in Web Editor NEWProvides the STM32Cube MCU Component "hal_driver" for the STM32WL series.
License: BSD 3-Clause "New" or "Revised" License
Provides the STM32Cube MCU Component "hal_driver" for the STM32WL series.
License: BSD 3-Clause "New" or "Revised" License
Hello, I am trying to use the LORA-E5 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?
#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
int8_t bme68x_start(struct bme68x_data *dataPtr) {
// Init.
bme68x_interface_init(&bme, BME68X_I2C_INTF);
// Init. for data variable
BME68x_DATA = dataPtr;
// Configuration
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.
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;
}
int8_t bme68x_single_measure(struct bme68x_data *dataPtr) {
bme68x_set_op_mode(BME68X_FORCED_MODE, &bme);
del_period = bme68x_get_meas_dur(BME68X_FORCED_MODE, &conf, &bme)
+ (heatr_conf.heatr_dur * 1000);
bme.delay_us(del_period, bme.intf_ptr);
rslt = bme68x_get_data(BME68X_FORCED_MODE, dataPtr, &n_fields, &bme);
return rslt;
}
// 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;
}
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;
}
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
do
{
hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress);
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))
{
hi2c->State = HAL_I2C_STATE_READY;
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);
}
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;
}
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
hi2c->State = HAL_I2C_STATE_READY;
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_ERROR;
}
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
}
if (I2C_Trials == Trials)
{
hi2c->Instance->CR2 |= I2C_CR2_STOP;
if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_ERROR;
}
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
}
I2C_Trials++;
} while (I2C_Trials < Trials);
hi2c->State = HAL_I2C_STATE_READY;
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
else
{
return HAL_BUSY;
}
}
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) and tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) always still “reset”
When I want config stm32wl usart tx logic level in reversion, I have to init UART such as:
huart2.Instance = USART1;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
// config UART advance feature
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_DATAINVERT_INIT | UART_ADVFEATURE_TXINVERT_INIT;
huart2.AdvancedInit.TxPinLevelInvert = USART_CR2_TXINV;
huart2.AdvancedInit.DataInvert = USART_CR2_DATAINV;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
The config code of advanced feature look tedious and mistake-prone without help of cubemx,maybe the define AdvancedInit
as uint32_t
instead of UART_AdvFeatureInitTypeDef
, only assign value to huart2.AdvancedInit.AdvFeatureInit
, then UART_AdvFeatureConfig
do well the remaining work. that looks more resonable
Hi there!
See here:
https://github.com/STMicroelectronics/stm32wlxx_hal_driver/blob/main/Src/stm32wlxx_hal_subghz.c#L269
https://github.com/STMicroelectronics/stm32wlxx_hal_driver/blob/main/Src/stm32wlxx_hal_subghz.c#L303
https://github.com/STMicroelectronics/stm32wlxx_hal_driver/blob/main/Src/stm32wlxx_hal_subghz.c#L369
These line test if "CM0PLUS" is defined but the STM32CubeIDE generated dual core project defines "CORE_CM0PLUS". Is this a mistake?
thanks in advance,
Pieter
I was looking at the LL_GPIO_Init
function and I noticed the function LL_GPIO_SetPinMode
is called twice in this function. The first time is near the beginning of the function on line 178:
stm32wlxx_hal_driver/Src/stm32wlxx_ll_gpio.c
Line 178 in d25d454
stm32wlxx_hal_driver/Src/stm32wlxx_ll_gpio.c
Line 215 in d25d454
By calling LL_GPIO_SetPinMode
before the various GPIO parameters are configured, it can cause unexpected behavior on the pins. I was configuring port PA2 as LPUART1_TX, and it was unexpectedly outputting a byte over UART when being configured. Removing the LL_GPIO_SetPinMode
on line 178 and only calling it on line 215 fixed this bug.
Unless there is some reason to call this function twice, I believe this is a bug.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.