Skip to content

Commit 1de5f9d

Browse files
committed
feat(I3C): adding support for I3C
Signed-off-by: Aymane Bahssain <aymane.bahssain@st.com>
1 parent c659c03 commit 1de5f9d

3 files changed

Lines changed: 171 additions & 2 deletions

File tree

CMakeLists.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# v3.21 implemented semantic changes regarding $<TARGET_OBJECTS:...>
2+
# See https://cmake.org/cmake/help/v3.21/command/target_link_libraries.html#linking-object-libraries-via-target-objects
3+
cmake_minimum_required(VERSION 3.21)
4+
5+
add_library(LPS22DF INTERFACE)
6+
add_library(LPS22DF_usage INTERFACE)
7+
8+
target_include_directories(LPS22DF_usage INTERFACE
9+
src
10+
)
11+
12+
13+
target_link_libraries(LPS22DF_usage INTERFACE
14+
base_config
15+
)
16+
17+
target_link_libraries(LPS22DF INTERFACE LPS22DF_usage)
18+
19+
20+
21+
add_library(LPS22DF_bin OBJECT EXCLUDE_FROM_ALL
22+
src/lps22df_reg.c
23+
src/LPS22DFSensor.cpp
24+
)
25+
target_link_libraries(LPS22DF_bin PUBLIC LPS22DF_usage)
26+
27+
target_link_libraries(LPS22DF INTERFACE
28+
LPS22DF_bin
29+
$<TARGET_OBJECTS:LPS22DF_bin>
30+
)
31+

src/LPS22DFSensor.cpp

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,32 @@ LPS22DFSensor::LPS22DFSensor(SPIClass *spi, int cs_pin, uint32_t spi_speed) : de
7171
enabled = 0L;
7272
}
7373

74+
LPS22DFSensor::LPS22DFSensor(I3CBus *i3c, uint8_t staticAddr7, uint8_t dynAddr7)
75+
{
76+
reg_ctx.write_reg = LPS22DF_io_write;
77+
reg_ctx.read_reg = LPS22DF_io_read;
78+
reg_ctx.handle = (void *)this;
79+
80+
dev_i2c = NULL;
81+
dev_spi = NULL;
82+
dev_i3c = i3c;
83+
84+
address = (dynAddr7 != 0) ? dynAddr7 : staticAddr7;
85+
i3c_static7 = staticAddr7;
86+
i3c_dyn7 = dynAddr7;
87+
88+
enabled = 0U;
89+
initialized = 0U;
90+
91+
bus_type = LPS22DF_I3C_BUS;
92+
}
93+
94+
void LPS22DFSensor::set_address(uint8_t dynAddr7)
95+
{
96+
97+
address = dynAddr7;
98+
}
99+
74100
/**
75101
* @brief Configure the sensor in order to be used
76102
* @retval 0 in case of success, an error code otherwise
@@ -86,21 +112,62 @@ LPS22DFStatusTypeDef LPS22DFSensor::begin()
86112
digitalWrite(cs_pin, HIGH);
87113
}
88114

115+
if (dev_i3c != nullptr) {
116+
Serial.println("I3C");
117+
118+
bool doAutoSetdasa = (i3c_static7 != 0) && (i3c_dyn7 != 0);
119+
120+
if (doAutoSetdasa) {
121+
dev_i3c->setClock(1000000); // 1 MHz mixte I3C+I2C
122+
123+
if (dev_i3c->assignDynamicAddress(i3c_static7, i3c_dyn7) != 0) {
124+
Serial.println("I3C: SETDASA failed");
125+
return LPS22DF_ERROR;
126+
}
127+
128+
address = i3c_dyn7;
129+
130+
uint8_t id = 0;
131+
if (ReadID(&id) != LPS22DF_OK || id != LPS22DF_ID) {
132+
Serial.print("I3C: probe failed after SETDASA, id=0x");
133+
Serial.println(id, HEX);
134+
return LPS22DF_ERROR;
135+
}
136+
137+
Serial.println("I3C: dynamic address and WHO_AM_I OK");
138+
} else {
139+
140+
uint8_t id = 0;
141+
if (ReadID(&id) != LPS22DF_OK || id != LPS22DF_ID) {
142+
Serial.print("I3C: manual mode: WHO_AM_I failed, id=0x");
143+
Serial.println(id, HEX);
144+
return LPS22DF_ERROR;
145+
}
146+
Serial.println("I3C: manual mode, WHO_AM_I OK at address 0x");
147+
Serial.println(address, HEX);
148+
}
149+
dev_i3c->setClock(12500000);
150+
}
151+
89152
/* Set bdu and if_inc recommended for driver usage */
90153
if (lps22df_init_set(&reg_ctx, LPS22DF_DRV_RDY) != LPS22DF_OK) {
91154
return LPS22DF_ERROR;
92155
}
93156

94157
/* Select bus interface */
95-
if (bus_type == LPS22DF_SPI_3WIRES_BUS) { /* SPI 3-Wires */
158+
if (bus_type == LPS22DF_SPI_3WIRES_BUS) {
96159
bus_mode.interface = lps22df_bus_mode_t::LPS22DF_SPI_3W;
97-
} else if (bus_type == LPS22DF_SPI_4WIRES_BUS) { /* SPI 3-Wires */
160+
} else if (bus_type == LPS22DF_SPI_4WIRES_BUS) {
98161
bus_mode.interface = lps22df_bus_mode_t::LPS22DF_SPI_4W;
162+
} else if (bus_type == LPS22DF_I3C_BUS) {
163+
bus_mode.interface = lps22df_bus_mode_t::LPS22DF_INT_PIN_ON_I3C;
99164
} else {
100165
bus_mode.interface = lps22df_bus_mode_t::LPS22DF_SEL_BY_HW;
101166
}
102167

103168
bus_mode.filter = lps22df_bus_mode_t::LPS22DF_AUTO;
169+
bus_mode.i3c_ibi_time = lps22df_bus_mode_t::LPS22DF_IBI_1ms;
170+
104171
if (lps22df_bus_mode_set(&reg_ctx, &bus_mode) != LPS22DF_OK) {
105172
return LPS22DF_ERROR;
106173
}
@@ -501,3 +568,39 @@ int32_t LPS22DF_io_read(void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16
501568
{
502569
return ((LPS22DFSensor *)handle)->IO_Read(pBuffer, ReadAddr, nBytesToRead);
503570
}
571+
572+
LPS22DFStatusTypeDef LPS22DFSensor::ConfigureDataReadyOnI3cIbi()
573+
{
574+
if (dev_i3c == nullptr) {
575+
return LPS22DF_ERROR;
576+
}
577+
578+
if (Write_Reg(LPS22DF_IF_CTRL, 0x80) != LPS22DF_OK) {
579+
return LPS22DF_ERROR;
580+
}
581+
582+
if (Write_Reg(LPS22DF_CTRL_REG4, 0x30) != LPS22DF_OK) {
583+
return LPS22DF_ERROR;
584+
}
585+
586+
return LPS22DF_OK;
587+
}
588+
589+
LPS22DFStatusTypeDef LPS22DFSensor::EnableIbiOnBus(uint8_t targetIndex,
590+
uint32_t timeoutMs,
591+
bool withPayload)
592+
{
593+
if (dev_i3c == nullptr) {
594+
return LPS22DF_ERROR;
595+
}
596+
597+
if (dev_i3c->enableIbi(targetIndex, address, withPayload, false, timeoutMs) != 0) {
598+
return LPS22DF_ERROR;
599+
}
600+
601+
if (dev_i3c->enableControllerEvents(HAL_I3C_IT_IBIIE) != 0) {
602+
return LPS22DF_ERROR;
603+
}
604+
605+
return LPS22DF_OK;
606+
}

src/LPS22DFSensor.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,23 @@
5353
#include "Wire.h"
5454
#include "SPI.h"
5555
#include "lps22df_reg.h"
56+
#include "I3C.h"
5657

5758

5859
/* Defines -------------------------------------------------------------------*/
5960

6061
#define LPS22DF_I2C_BUS 0U
6162
#define LPS22DF_SPI_4WIRES_BUS 1U
6263
#define LPS22DF_SPI_3WIRES_BUS 2U
64+
#define LPS22DF_I3C_BUS 3U
65+
66+
/** I3C/I2C Device Static Address 7 bit format if SA0=0 -> 0x5C if SA0=1 -> 0x5D **/
67+
#define LPS22DF_I3C_ADD_L 0x5CU
68+
#define LPS22DF_I3C_ADD_H 0x5DU
69+
70+
/** I3C/I2C Device PID**/
71+
static const uint64_t LPS22DF_I3C_PID_L = 0x020800B4100BULL;
72+
static const uint64_t LPS22DF_I3C_PID_H = 0x020800B4900BULL;
6373

6474

6575
/* Typedefs ------------------------------------------------------------------*/
@@ -79,6 +89,7 @@ class LPS22DFSensor {
7989
public:
8090
LPS22DFSensor(TwoWire *i2c, uint8_t address = LPS22DF_I2C_ADD_H);
8191
LPS22DFSensor(SPIClass *spi, int cs_pin, uint32_t spi_speed = 2000000);
92+
LPS22DFSensor(I3CBus *i3c, uint8_t staticAddr7 = 0, uint8_t dynAddr7 = 0);
8293

8394
LPS22DFStatusTypeDef begin();
8495
LPS22DFStatusTypeDef end();
@@ -100,6 +111,13 @@ class LPS22DFSensor {
100111
LPS22DFStatusTypeDef Set_One_Shot();
101112
LPS22DFStatusTypeDef Get_One_Shot_Status(uint8_t *Status);
102113

114+
LPS22DFStatusTypeDef ConfigureDataReadyOnI3cIbi();
115+
LPS22DFStatusTypeDef EnableIbiOnBus(uint8_t targetIndex = 1,
116+
uint32_t timeoutMs = 1000,
117+
bool withPayload = true);
118+
119+
void set_address(uint8_t dynAddr7);
120+
103121
/**
104122
* @brief Utility function to read data.
105123
* @param pBuffer: pointer to data to be read.
@@ -144,6 +162,13 @@ class LPS22DFSensor {
144162
return 0;
145163
}
146164

165+
if (dev_i3c) {
166+
if (dev_i3c->readRegBuffer(address, RegisterAddr, pBuffer, NumByteToRead) == 0) {
167+
return 0;
168+
}
169+
return 1;
170+
}
171+
147172
return 1;
148173
}
149174

@@ -187,6 +212,12 @@ class LPS22DFSensor {
187212

188213
return 0;
189214
}
215+
if (dev_i3c) {
216+
if (dev_i3c->writeRegBuffer(address, RegisterAddr, pBuffer, NumByteToWrite) == 0) {
217+
return 0;
218+
}
219+
return 1;
220+
}
190221

191222
return 1;
192223
}
@@ -198,6 +229,7 @@ class LPS22DFSensor {
198229
/* Helper classes. */
199230
TwoWire *dev_i2c;
200231
SPIClass *dev_spi;
232+
I3CBus *dev_i3c;
201233

202234
uint32_t bus_type; /*0 means I2C, 1 means SPI 4-Wires, 2 means SPI-3-Wires */
203235
uint8_t initialized;
@@ -209,6 +241,9 @@ class LPS22DFSensor {
209241
int cs_pin;
210242
uint32_t spi_speed;
211243

244+
uint8_t i3c_static7;
245+
uint8_t i3c_dyn7;
246+
212247
lps22df_ctx_t reg_ctx;
213248
};
214249

0 commit comments

Comments
 (0)