diff --git a/.github/workflows/Continuous-integration.yml b/.github/workflows/Continuous-integration.yml index 7d9340a..20d3a6e 100644 --- a/.github/workflows/Continuous-integration.yml +++ b/.github/workflows/Continuous-integration.yml @@ -59,8 +59,10 @@ jobs: id: compile uses: stm32duino/actions/compile-examples@main with: - board-pattern: "NUCLEO_L476RG" - + custom-config: "./extras/build_config.json" + board-pattern: "NUCLEO_L476RG|NUCLEO_H503RB" + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} # Use the output from the `Compilation` step - name: Compilation Errors if: failure() diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..942a9fa --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +# v3.21 implemented semantic changes regarding $ +# See https://cmake.org/cmake/help/v3.21/command/target_link_libraries.html#linking-object-libraries-via-target-objects +cmake_minimum_required(VERSION 3.21) + +add_library(LPS22DF INTERFACE) +add_library(LPS22DF_usage INTERFACE) + +target_include_directories(LPS22DF_usage INTERFACE + src +) + + +target_link_libraries(LPS22DF_usage INTERFACE + base_config +) + +target_link_libraries(LPS22DF INTERFACE LPS22DF_usage) + + + +add_library(LPS22DF_bin OBJECT EXCLUDE_FROM_ALL + src/lps22df_reg.c + src/LPS22DFSensor.cpp +) +target_link_libraries(LPS22DF_bin PUBLIC LPS22DF_usage) + +target_link_libraries(LPS22DF INTERFACE + LPS22DF_bin + $ +) + diff --git a/README.md b/README.md index e79e23a..4aaa705 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Arduino library to support the LPS22DF 260-1260 hPa absolute digital output baro ## API -This sensor uses I2C or SPI to communicate. +This sensor uses I2C, SPI or I3C to communicate. For I2C it is then required to create a TwoWire interface before accessing to the sensors: TwoWire dev_i2c(I2C_SDA, I2C_SCL); @@ -27,6 +27,26 @@ An instance can be created and enabled when the SPI bus is used following the pr PressTemp.begin(); PressTemp.Enable(); +An instance can be created and enabled when the I3C bus is used with SETDASA (static-to-dynamic address assignment): + + LPS22DFSensor PressTemp(&I3C, LPS22DF_I3C_ADD_H); + I3C.begin(I3C_SDA, I3C_SCL, 1000000U); + I3C.resetDynamicAddresses(); + I3C.assignDynamicAddress(PressTemp.getStaticAddress(), LPS22DF_DYNAMIC_ADDRESS); + PressTemp.begin(LPS22DF_DYNAMIC_ADDRESS); + I3C.setClock(12500000); + PressTemp.Enable(); + +An instance can be created and enabled when the I3C bus is used with ENTDAA (dynamic address discovery): + + LPS22DFSensor PressTemp(&I3C); + I3C.begin(I3C_SDA, I3C_SCL, 1000000U); + I3C.discover(devices, 8, &found); + // find dynAddr by matching LPS22DF_I3C_PID_H in discovered devices + PressTemp.begin(dynAddr); + I3C.setClock(12500000); + PressTemp.Enable(); + The access to the sensor values is done as explained below: Read pressure and temperature. diff --git a/examples/LPS22DF_DataLog_Terminal/LPS22DF_DataLog_Terminal.ino b/examples/LPS22DF_DataLog_Terminal_I2C/LPS22DF_DataLog_Terminal_I2C.ino similarity index 84% rename from examples/LPS22DF_DataLog_Terminal/LPS22DF_DataLog_Terminal.ino rename to examples/LPS22DF_DataLog_Terminal_I2C/LPS22DF_DataLog_Terminal_I2C.ino index e74b837..542d8cf 100644 --- a/examples/LPS22DF_DataLog_Terminal/LPS22DF_DataLog_Terminal.ino +++ b/examples/LPS22DF_DataLog_Terminal_I2C/LPS22DF_DataLog_Terminal_I2C.ino @@ -1,8 +1,8 @@ /* - @file LPS22DF_DataLog_Terminal.ino + @file LPS22DF_DataLog_Terminal_I2C.ino @author Giuseppe Roberti @brief Example to use the LPS22DF 260-1260 hPa absolute digital - output barometer + output barometer with I2C bus ******************************************************************************* Copyright (c) 2022, STMicroelectronics All rights reserved. @@ -15,18 +15,21 @@ #include -LPS22DFSensor sensor (&Wire); +LPS22DFSensor sensor(&Wire); float pressure, temperature; -void setup() { +void setup() +{ pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); Wire.begin(); sensor.begin(); sensor.Enable(); + Serial.println("LPS22DF ready"); } -void loop() { +void loop() +{ sensor.GetPressure(&pressure); sensor.GetTemperature(&temperature); @@ -38,7 +41,8 @@ void loop() { blink(LED_BUILTIN); } -inline void blink(int pin) { +inline void blink(int pin) +{ digitalWrite(pin, HIGH); delay(25); digitalWrite(pin, LOW); diff --git a/examples/LPS22DF_DataLog_Terminal_I3C/LPS22DF_DataLog_Terminal_I3C.ino b/examples/LPS22DF_DataLog_Terminal_I3C/LPS22DF_DataLog_Terminal_I3C.ino new file mode 100644 index 0000000..b66011f --- /dev/null +++ b/examples/LPS22DF_DataLog_Terminal_I3C/LPS22DF_DataLog_Terminal_I3C.ino @@ -0,0 +1,78 @@ +/* + @file LPS22DF_DataLog_Terminal_I3C.ino + @author STMicroelectronics + @brief Example to use the LPS22DF pressure sensor with I3C and SETDASA command + ******************************************************************************* + Copyright (c) 2026, STMicroelectronics + All rights reserved. + + This software component is licensed by ST under BSD 3-Clause license, + the "License"; You may not use this file except in compliance with the + License. You may obtain a copy of the License at: + opensource.org/licenses/BSD-3-Clause + + ******************************************************************************* +*/ +#include "LPS22DFSensor.h" + +#define LPS22DF_DYNAMIC_ADDRESS 0x30 + +LPS22DFSensor sensor(&I3C, LPS22DF_I3C_ADD_H); + +void setup() +{ + Serial.begin(115200); + while (!Serial) {} + delay(1000); + + Serial.println("=== LPS22DF SETDASA ==="); + + if (!I3C.begin(I3C_SDA, I3C_SCL, 1000000U)) { + Serial.println("begin() failed"); + while (1) {} + } + + if (!I3C.resetDynamicAddresses()) { + Serial.println("resetDynamicAddresses() failed"); + while (1) {} + } + + if (!I3C.assignDynamicAddress(sensor.getStaticAddress(), LPS22DF_DYNAMIC_ADDRESS)) { + Serial.println("assignDynamicAddress() failed"); + while (1) {} + } + + if (sensor.begin(LPS22DF_DYNAMIC_ADDRESS) != LPS22DF_OK) { + Serial.println("sensor.begin() failed"); + while (1) {} + } + + if (!I3C.setClock(12500000)) { + Serial.println("setClock() failed"); + while (1) {} + } + + if (sensor.Enable() != LPS22DF_OK) { + Serial.println("sensor.Enable() failed"); + while (1) {} + } + + Serial.println("LPS22DF ready"); +} + +void loop() +{ + float pressure = 0.0f; + float temperature = 0.0f; + + if (sensor.GetPressure(&pressure) == LPS22DF_OK && sensor.GetTemperature(&temperature) == LPS22DF_OK) { + Serial.print("Pressure[hPa]:"); + Serial.print(pressure, 2); + Serial.print(", Temperature[C]:"); + Serial.println(temperature, 2); + } else { + Serial.println("Read failed"); + } + + delay(500); +} diff --git a/examples/LPS22DF_DataLog_Terminal_I3C_ENTDAA/LPS22DF_DataLog_Terminal_I3C_ENTDAA.ino b/examples/LPS22DF_DataLog_Terminal_I3C_ENTDAA/LPS22DF_DataLog_Terminal_I3C_ENTDAA.ino new file mode 100644 index 0000000..afa26a5 --- /dev/null +++ b/examples/LPS22DF_DataLog_Terminal_I3C_ENTDAA/LPS22DF_DataLog_Terminal_I3C_ENTDAA.ino @@ -0,0 +1,97 @@ +/* + @file LPS22DF_DataLog_Terminal_I3C_ENTDAA.ino + @author STMicroelectronics + @brief Example to use the LPS22DF pressure sensor with I3C dynamic address assignment + ******************************************************************************* + Copyright (c) 2026, STMicroelectronics + All rights reserved. + + This software component is licensed by ST under BSD 3-Clause license, + the "License"; You may not use this file except in compliance with the + License. You may obtain a copy of the License at: + opensource.org/licenses/BSD-3-Clause + + ******************************************************************************* +*/ + +#include "LPS22DFSensor.h" + +LPS22DFSensor sensor(&I3C); + +void setup() +{ + Serial.begin(115200); + while (!Serial) {} + delay(1000); + + Serial.println("=== LPS22DF DAA ==="); + + if (!I3C.begin(I3C_SDA, I3C_SCL, 1000000U)) { + Serial.println("begin() failed"); + while (1) {} + } + + if (!I3C.resetDynamicAddresses()) { + Serial.println("resetDynamicAddresses() failed"); + while (1) {} + } + + I3CDiscoveredDevice devices[8] {}; + size_t found = 0; + + if (I3C.discover(devices, 8, &found)) { + Serial.println("discover() failed"); + while (1) {} + } + + uint8_t lpsDynAddr = 0U; + + for (size_t i = 0; i < found; ++i) { + Serial.println(devices[i].pid, HEX); + if (devices[i].pid == LPS22DF_I3C_PID_H) { + lpsDynAddr = devices[i].dynAddr; + Serial.print("lpsDynAddr="); + Serial.println(lpsDynAddr, HEX); + break; + } + } + + if (lpsDynAddr == 0U) { + Serial.println("Sensor not found"); + while (1) {} + } + + if (sensor.begin(lpsDynAddr) != LPS22DF_OK) { + Serial.println("sensor.begin() failed"); + while (1) {} + } + + if (!I3C.setClock(12500000)) { + Serial.println("setClock() failed"); + while (1) {} + } + + if (sensor.Enable() != LPS22DF_OK) { + Serial.println("sensor.Enable() failed"); + while (1) {} + } + + Serial.println("LPS22DF ready"); +} + +void loop() +{ + float pressure = 0.0f; + float temperature = 0.0f; + + if (sensor.GetPressure(&pressure) == LPS22DF_OK && sensor.GetTemperature(&temperature) == LPS22DF_OK) { + Serial.print("Pressure[hPa]:"); + Serial.print(pressure, 2); + Serial.print(", Temperature[C]:"); + Serial.println(temperature, 2); + } else { + Serial.println("Read failed"); + } + + delay(500); +} diff --git a/extras/build_config.json b/extras/build_config.json new file mode 100644 index 0000000..9253f07 --- /dev/null +++ b/extras/build_config.json @@ -0,0 +1,25 @@ +{ + "cores": [ + { + "maintainer": "STMicroelectronics", + "architecture": "stm32", + "boards": [ + ], + "sketches": [ + { + "pattern": "[^I][^3][^C]", + "applicable": true, + "boards": [ + "NUCLEO_L476RG", + "NUCLEO_H503RB" + ] + }, + { + "pattern": "I3C", + "applicable": true, + "boards": [ "NUCLEO_H503RB"] + } + ] + } + ] +} diff --git a/extras/codespell-ignore-words-list.txt b/extras/codespell-ignore-words-list.txt index 6f65d22..8df130b 100644 --- a/extras/codespell-ignore-words-list.txt +++ b/extras/codespell-ignore-words-list.txt @@ -1 +1,2 @@ +daa ths \ No newline at end of file diff --git a/keywords.txt b/keywords.txt index adbc4b8..820e690 100644 --- a/keywords.txt +++ b/keywords.txt @@ -27,6 +27,8 @@ Read_Reg KEYWORD2 Write_Reg KEYWORD2 Set_One_Shot KEYWORD2 Get_One_Shot_Status KEYWORD2 +getStaticAddress KEYWORD2 +getDynAddress KEYWORD2 ####################################### # Constants (LITERAL1) @@ -34,3 +36,11 @@ Get_One_Shot_Status KEYWORD2 LPS22DF_OK LITERAL1 LPS22DF_ERROR LITERAL1 +LPS22DF_I2C_BUS LITERAL1 +LPS22DF_SPI_4WIRES_BUS LITERAL1 +LPS22DF_SPI_3WIRES_BUS LITERAL1 +LPS22DF_I3C_BUS LITERAL1 +LPS22DF_I3C_ADD_L LITERAL1 +LPS22DF_I3C_ADD_H LITERAL1 +LPS22DF_I3C_PID_L LITERAL1 +LPS22DF_I3C_PID_H LITERAL1 diff --git a/library.properties b/library.properties index 0e085ff..68d19d2 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=STM32duino LPS22DF -version=1.0.4 +version=1.1.0 author=SRA maintainer=stm32duino sentence=Nano pressure sensor. diff --git a/src/LPS22DFSensor.cpp b/src/LPS22DFSensor.cpp index 70d11ee..5b07503 100644 --- a/src/LPS22DFSensor.cpp +++ b/src/LPS22DFSensor.cpp @@ -2,8 +2,8 @@ ****************************************************************************** * @file LPS22DFSensor.cpp * @author SRA - * @version V1.0.1 - * @date July 2022 + * @version V1.1.0 + * @date July 2026 * @brief Implementation of a LPS22DF pressure sensor. ****************************************************************************** * @attention @@ -53,6 +53,9 @@ LPS22DFSensor::LPS22DFSensor(TwoWire *i2c, uint8_t address) : dev_i2c(i2c), addr reg_ctx.read_reg = LPS22DF_io_read; reg_ctx.handle = (void *)this; dev_spi = NULL; +#if defined(I3C_SUPPORTED) + dev_i3c = NULL; +#endif enabled = 0L; } @@ -67,15 +70,49 @@ LPS22DFSensor::LPS22DFSensor(SPIClass *spi, int cs_pin, uint32_t spi_speed) : de reg_ctx.read_reg = LPS22DF_io_read; reg_ctx.handle = (void *)this; dev_i2c = NULL; +#if defined(I3C_SUPPORTED) + dev_i3c = NULL; +#endif address = 0L; enabled = 0L; } +#if defined(I3C_SUPPORTED) +LPS22DFSensor::LPS22DFSensor(I3CBus *i3c, uint8_t static_addr7) +{ + reg_ctx.write_reg = LPS22DF_io_write; + reg_ctx.read_reg = LPS22DF_io_read; + reg_ctx.handle = (void *)this; + + dev_i2c = NULL; + dev_spi = NULL; + dev_i3c = i3c; + + address = static_addr7; + i3c_static7 = static_addr7; + i3c_dyn7 = 0; + + enabled = 0U; + initialized = 0U; + + bus_type = LPS22DF_I3C_BUS; +} + +uint8_t LPS22DFSensor::getStaticAddress() const +{ + return i3c_static7; +} +uint8_t LPS22DFSensor::getDynAddress() const +{ + return i3c_dyn7; +} +#endif + /** * @brief Configure the sensor in order to be used * @retval 0 in case of success, an error code otherwise */ -LPS22DFStatusTypeDef LPS22DFSensor::begin() +LPS22DFStatusTypeDef LPS22DFSensor::begin(uint8_t new_address) { lps22df_md_t md; lps22df_bus_mode_t bus_mode; @@ -86,21 +123,43 @@ LPS22DFStatusTypeDef LPS22DFSensor::begin() digitalWrite(cs_pin, HIGH); } +#if defined(I3C_SUPPORTED) + if (dev_i3c != nullptr) { + if (new_address < 0x08 || new_address > 0x77) { + return LPS22DF_ERROR; + } else { + address = new_address; + i3c_dyn7 = new_address; + } + uint8_t id = 0; + if (ReadID(&id) != LPS22DF_OK || id != LPS22DF_ID) { + return LPS22DF_ERROR; + } + } +#endif + /* Set bdu and if_inc recommended for driver usage */ if (lps22df_init_set(®_ctx, LPS22DF_DRV_RDY) != LPS22DF_OK) { return LPS22DF_ERROR; } /* Select bus interface */ - if (bus_type == LPS22DF_SPI_3WIRES_BUS) { /* SPI 3-Wires */ + if (bus_type == LPS22DF_SPI_3WIRES_BUS) { bus_mode.interface = lps22df_bus_mode_t::LPS22DF_SPI_3W; - } else if (bus_type == LPS22DF_SPI_4WIRES_BUS) { /* SPI 3-Wires */ + } else if (bus_type == LPS22DF_SPI_4WIRES_BUS) { bus_mode.interface = lps22df_bus_mode_t::LPS22DF_SPI_4W; - } else { + } +#if defined(I3C_SUPPORTED) + else if (bus_type == LPS22DF_I3C_BUS) { + bus_mode.interface = lps22df_bus_mode_t::LPS22DF_INT_PIN_ON_I3C; + } +#endif + else { bus_mode.interface = lps22df_bus_mode_t::LPS22DF_SEL_BY_HW; } bus_mode.filter = lps22df_bus_mode_t::LPS22DF_AUTO; + if (lps22df_bus_mode_set(®_ctx, &bus_mode) != LPS22DF_OK) { return LPS22DF_ERROR; } @@ -501,3 +560,4 @@ int32_t LPS22DF_io_read(void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16 { return ((LPS22DFSensor *)handle)->IO_Read(pBuffer, ReadAddr, nBytesToRead); } + diff --git a/src/LPS22DFSensor.h b/src/LPS22DFSensor.h index 42cd083..cbd31b6 100644 --- a/src/LPS22DFSensor.h +++ b/src/LPS22DFSensor.h @@ -41,6 +41,10 @@ #ifndef __LPS22DFSensor_H__ #define __LPS22DFSensor_H__ +/* Core compatibility --------------------------------------------------------*/ +#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION <= 0x020C0000) + #error "This library is not compatible with core version used. Please update the core." +#endif /* Includes ------------------------------------------------------------------*/ /* For compatibility with ESP32 platforms */ @@ -54,13 +58,27 @@ #include "SPI.h" #include "lps22df_reg.h" +#if (defined(I3C1_BASE) || defined(I3C2_BASE)) && !defined(I3C_SUPPORTED) + #define I3C_SUPPORTED + #include "I3C.h" +#endif /* Defines -------------------------------------------------------------------*/ #define LPS22DF_I2C_BUS 0U #define LPS22DF_SPI_4WIRES_BUS 1U #define LPS22DF_SPI_3WIRES_BUS 2U +#if defined(I3C_SUPPORTED) + #define LPS22DF_I3C_BUS 3U + /** I3C/I2C Device Static Address 7 bit format if SA0=0 -> 0x5C if SA0=1 -> 0x5D **/ + #define LPS22DF_I3C_ADD_L 0x5CU + #define LPS22DF_I3C_ADD_H 0x5DU + + /** I3C/I2C Device PID**/ + static const uint64_t LPS22DF_I3C_PID_L = 0x020800B4100BULL; + static const uint64_t LPS22DF_I3C_PID_H = 0x020800B4900BULL; +#endif /* Typedefs ------------------------------------------------------------------*/ @@ -79,8 +97,11 @@ class LPS22DFSensor { public: LPS22DFSensor(TwoWire *i2c, uint8_t address = LPS22DF_I2C_ADD_H); LPS22DFSensor(SPIClass *spi, int cs_pin, uint32_t spi_speed = 2000000); +#if defined(I3C_SUPPORTED) + LPS22DFSensor(I3CBus *i3c, uint8_t static_addr7 = 0); +#endif - LPS22DFStatusTypeDef begin(); + LPS22DFStatusTypeDef begin(uint8_t new_address = 0); LPS22DFStatusTypeDef end(); LPS22DFStatusTypeDef ReadID(uint8_t *Id); LPS22DFStatusTypeDef Enable(); @@ -100,6 +121,11 @@ class LPS22DFSensor { LPS22DFStatusTypeDef Set_One_Shot(); LPS22DFStatusTypeDef Get_One_Shot_Status(uint8_t *Status); +#if defined(I3C_SUPPORTED) + uint8_t getStaticAddress() const; + uint8_t getDynAddress() const; +#endif + /** * @brief Utility function to read data. * @param pBuffer: pointer to data to be read. @@ -144,6 +170,14 @@ class LPS22DFSensor { return 0; } +#if defined(I3C_SUPPORTED) + if (dev_i3c) { + if (dev_i3c->readRegBuffer(address, RegisterAddr, pBuffer, NumByteToRead) == 0) { + return 0; + } + } +#endif + return 1; } @@ -188,6 +222,15 @@ class LPS22DFSensor { return 0; } +#if defined(I3C_SUPPORTED) + if (dev_i3c) { + if (dev_i3c->writeRegBuffer(address, RegisterAddr, pBuffer, NumByteToWrite) == 0) { + return 0; + } + return 1; + } +#endif + return 1; } @@ -198,6 +241,9 @@ class LPS22DFSensor { /* Helper classes. */ TwoWire *dev_i2c; SPIClass *dev_spi; +#if defined(I3C_SUPPORTED) + I3CBus *dev_i3c; +#endif uint32_t bus_type; /*0 means I2C, 1 means SPI 4-Wires, 2 means SPI-3-Wires */ uint8_t initialized; @@ -209,6 +255,11 @@ class LPS22DFSensor { int cs_pin; uint32_t spi_speed; +#if defined(I3C_SUPPORTED) + uint8_t i3c_static7; + uint8_t i3c_dyn7; +#endif + lps22df_ctx_t reg_ctx; };