Skip to content

Commit 9e59746

Browse files
committed
feat(i3c): support automatic instance selection from SDA/SCL pins
Signed-off-by: Aymane Bahssain <aymane.bahssain@st.com>
1 parent 6ee897a commit 9e59746

2 files changed

Lines changed: 75 additions & 60 deletions

File tree

‎libraries/I3C/src/I3C.cpp‎

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,7 @@
66
// ============================================================================
77
// Global bus instances
88
// ============================================================================
9-
10-
#if defined(I3C1)
11-
I3CBus I3C1Bus(I3C1);
12-
#endif
13-
14-
#if defined(I3C2)
15-
I3CBus I3C2Bus(I3C2);
16-
#endif
9+
I3CBus I3C;
1710

1811
// ============================================================================
1912
// File-local constants and helpers
@@ -98,6 +91,27 @@ extern "C" void HAL_I3C_NotifyCallback(I3C_HandleTypeDef *hi3c, uint32_t eventId
9891
}
9992
}
10093

94+
// ------------------------------------------------------------------------
95+
// instance
96+
// ------------------------------------------------------------------------
97+
bool I3CBus::prepareInstanceFromPins()
98+
{
99+
bool result = false;
100+
101+
if ((_sdaPin != NC) && (_sclPin != NC)) {
102+
void *merged = pinmap_merge_peripheral(
103+
pinmap_peripheral(_sdaPin, PinMap_I3C_SDA),
104+
pinmap_peripheral(_sclPin, PinMap_I3C_SCL));
105+
106+
if (merged != (void *)NP) {
107+
_instance = reinterpret_cast<I3C_TypeDef *>(merged);
108+
result = true;
109+
}
110+
}
111+
112+
return result;
113+
}
114+
101115
// ============================================================================
102116
// Low-level initialization
103117
// ============================================================================
@@ -106,16 +120,10 @@ bool I3CBus::initGPIO()
106120
{
107121
bool result = false;
108122

109-
if ((_sdaPin != NC) && (_sclPin != NC)) {
110-
void *periphSDA = pinmap_peripheral(_sdaPin, PinMap_I3C_SDA);
111-
void *periphSCL = pinmap_peripheral(_sclPin, PinMap_I3C_SCL);
112-
void *merged = pinmap_merge_peripheral(periphSDA, periphSCL);
113-
114-
if ((merged != (void *)NP) && (merged == _instance)) {
115-
pinmap_pinout(_sdaPin, PinMap_I3C_SDA);
116-
pinmap_pinout(_sclPin, PinMap_I3C_SCL);
117-
result = true;
118-
}
123+
if ((_sdaPin != NC) && (_sclPin != NC) && (_instance != nullptr)) {
124+
pinmap_pinout(_sdaPin, PinMap_I3C_SDA);
125+
pinmap_pinout(_sclPin, PinMap_I3C_SCL);
126+
result = true;
119127
}
120128

121129
return result;
@@ -229,7 +237,11 @@ bool I3CBus::begin(uint32_t freq,
229237
_mixedBusOdFreq = mixedOdHz;
230238
_ctrlCfg = ctrlCfg;
231239

232-
if (!initClocks()) {
240+
if (!prepareInstanceFromPins()) {
241+
local_ok = false;
242+
}
243+
244+
if (local_ok && !initClocks()) {
233245
local_ok = false;
234246
}
235247

@@ -677,10 +689,10 @@ bool I3CBus::isI3CDeviceReady(uint8_t dynAddr, uint32_t trials, uint32_t timeout
677689
// ============================================================================
678690

679691
bool I3CBus::cccBroadcastWrite(uint8_t cccId,
680-
const uint8_t *data,
681-
uint16_t length,
682-
bool withDefByte,
683-
uint32_t timeout)
692+
const uint8_t *data,
693+
uint16_t length,
694+
bool withDefByte,
695+
uint32_t timeout)
684696
{
685697
bool result = false;
686698

@@ -726,11 +738,11 @@ bool I3CBus::cccBroadcastWrite(uint8_t cccId,
726738
}
727739

728740
bool I3CBus::cccDirectWrite(uint8_t targetAddr,
729-
uint8_t cccId,
730-
const uint8_t *data,
731-
uint16_t length,
732-
bool withDefByte,
733-
uint32_t timeout)
741+
uint8_t cccId,
742+
const uint8_t *data,
743+
uint16_t length,
744+
bool withDefByte,
745+
uint32_t timeout)
734746
{
735747
bool result = false;
736748

@@ -776,10 +788,10 @@ bool I3CBus::cccDirectWrite(uint8_t targetAddr,
776788
}
777789

778790
bool I3CBus::cccDirectRead(uint8_t targetAddr,
779-
uint8_t cccId,
780-
uint8_t *rxData,
781-
uint16_t rxLength,
782-
uint32_t timeout)
791+
uint8_t cccId,
792+
uint8_t *rxData,
793+
uint16_t rxLength,
794+
uint32_t timeout)
783795
{
784796
bool result = false;
785797

@@ -938,9 +950,9 @@ bool I3CBus::rstactPeripheralOnly()
938950
}
939951

940952
bool I3CBus::setEvents(uint8_t dynAddr,
941-
bool enable,
942-
uint8_t events,
943-
uint32_t timeout)
953+
bool enable,
954+
uint8_t events,
955+
uint32_t timeout)
944956
{
945957
bool result = false;
946958

@@ -1442,7 +1454,11 @@ bool I3CBus::beginTarget(const I3CTargetConfig &cfg)
14421454
} else {
14431455
bool local_ok = true;
14441456

1445-
if (!initClocks()) {
1457+
if (!prepareInstanceFromPins()) {
1458+
local_ok = false;
1459+
}
1460+
1461+
if (local_ok && !initClocks()) {
14461462
local_ok = false;
14471463
}
14481464

‎libraries/I3C/src/I3C.h‎

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ struct I3CControllerConfig {
119119

120120
class I3CBus {
121121
public:
122-
explicit I3CBus(I3C_TypeDef *inst = I3C1) : _instance(inst) {}
122+
explicit I3CBus() : _instance(nullptr) {}
123123

124124
// ------------------------------------------------------------------------
125125
// Controller initialization and bus configuration
@@ -397,9 +397,9 @@ class I3CBus {
397397
int disableTargetEvents(uint32_t interruptMask);
398398

399399
bool setEvents(uint8_t dynAddr,
400-
bool enable,
401-
uint8_t events,
402-
uint32_t timeout = 1000U);
400+
bool enable,
401+
uint8_t events,
402+
uint32_t timeout = 1000U);
403403

404404
bool hasTargetEvent() const;
405405
bool readTargetEvent(uint32_t &eventId);
@@ -440,6 +440,11 @@ class I3CBus {
440440
}
441441

442442
private:
443+
// ------------------------------------------------------------------------
444+
// Instance
445+
// ------------------------------------------------------------------------
446+
bool prepareInstanceFromPins();
447+
443448
enum class I3CAddrState : uint8_t {
444449
Free,
445450
Reserved,
@@ -496,23 +501,23 @@ class I3CBus {
496501
// Low-level CCC helpers
497502
// ------------------------------------------------------------------------
498503
bool cccBroadcastWrite(uint8_t cccId,
499-
const uint8_t *data,
500-
uint16_t length,
501-
bool withDefByte,
502-
uint32_t timeout = 1000U);
504+
const uint8_t *data,
505+
uint16_t length,
506+
bool withDefByte,
507+
uint32_t timeout = 1000U);
503508

504509
bool cccDirectWrite(uint8_t targetAddr,
505-
uint8_t cccId,
506-
const uint8_t *data,
507-
uint16_t length,
508-
bool withDefByte,
509-
uint32_t timeout = 1000U);
510+
uint8_t cccId,
511+
const uint8_t *data,
512+
uint16_t length,
513+
bool withDefByte,
514+
uint32_t timeout = 1000U);
510515

511516
bool cccDirectRead(uint8_t targetAddr,
512-
uint8_t cccId,
513-
uint8_t *rxData,
514-
uint16_t rxLength,
515-
uint32_t timeout = 1000);
517+
uint8_t cccId,
518+
uint8_t *rxData,
519+
uint16_t rxLength,
520+
uint32_t timeout = 1000);
516521

517522
// ------------------------------------------------------------------------
518523
// Internal utility helpers
@@ -549,12 +554,6 @@ class I3CBus {
549554
// Global instances
550555
// ============================================================================
551556

552-
#if defined(I3C1)
553-
extern I3CBus I3C1Bus;
554-
#endif
555-
556-
#if defined(I3C2)
557-
extern I3CBus I3C2Bus;
558-
#endif
557+
extern I3CBus I3C;
559558

560559
#endif

0 commit comments

Comments
 (0)