Skip to content

Commit 17ee01c

Browse files
committed
fix(i3c): initialize controller bus timing before HAL init
Signed-off-by: Aymane Bahssain <aymane.bahssain@st.com>
1 parent 9e59746 commit 17ee01c

2 files changed

Lines changed: 115 additions & 35 deletions

File tree

‎libraries/I3C/src/I3C.cpp‎

Lines changed: 108 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,43 @@ bool I3CBus::begin(uint32_t freq,
254254
_hi3c.Instance = _instance;
255255
_hi3c.Mode = HAL_I3C_MODE_CONTROLLER;
256256

257+
I3C_CtrlTimingTypeDef inTiming {};
258+
LL_I3C_CtrlBusConfTypeDef outCtrl {};
259+
uint32_t srcFreq = 0U;
260+
261+
if (_instance == I3C1) {
262+
srcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I3C1);
263+
}
264+
#if defined(I3C2)
265+
else if (_instance == I3C2) {
266+
srcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I3C2);
267+
}
268+
#endif
269+
270+
if (srcFreq == 0U) {
271+
local_ok = false;
272+
} else {
273+
inTiming.clockSrcFreq = srcFreq;
274+
inTiming.i3cPPFreq = (freq == 0U) ? 1000000U : freq;
275+
inTiming.dutyCycle = 50U;
276+
277+
if (_busType == I3CBusType::Pure) {
278+
inTiming.busType = I3C_PURE_I3C_BUS;
279+
inTiming.i2cODFreq = 0U;
280+
} else {
281+
inTiming.busType = I3C_MIXED_BUS;
282+
inTiming.i2cODFreq = _mixedBusOdFreq;
283+
}
284+
285+
if (I3C_CtrlTimingComputation(&inTiming, &outCtrl) != SUCCESS) {
286+
local_ok = false;
287+
} else {
288+
_hi3c.Init.CtrlBusCharacteristic = outCtrl;
289+
}
290+
}
291+
}
292+
293+
if (local_ok) {
257294
if (HAL_I3C_Init(&_hi3c) != HAL_OK) {
258295
local_ok = false;
259296
}
@@ -342,44 +379,13 @@ int I3CBus::setClock(uint32_t i3cFreq)
342379

343380
if (!_initialized) {
344381
result = -1;
345-
} else if (i3cFreq == 0U) {
346-
result = 0;
347-
} else {
348-
I3C_CtrlTimingTypeDef inTiming {};
382+
} else if (i3cFreq != 0U) {
349383
LL_I3C_CtrlBusConfTypeDef outCtrl {};
350-
uint32_t srcFreq = 0U;
351-
352-
if (_instance == I3C1) {
353-
srcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I3C1);
354-
}
355-
#if defined(I3C2)
356-
else if (_instance == I3C2) {
357-
srcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I3C2);
358-
}
359-
#endif
360384

361-
if (srcFreq == 0U) {
385+
if (!buildControllerTiming(i3cFreq, outCtrl)) {
386+
result = -1;
387+
} else if (HAL_I3C_Ctrl_BusCharacteristicConfig(&_hi3c, &outCtrl) != HAL_OK) {
362388
result = -1;
363-
} else {
364-
inTiming.clockSrcFreq = srcFreq;
365-
inTiming.i3cPPFreq = i3cFreq;
366-
inTiming.dutyCycle = 50U;
367-
368-
if (_busType == I3CBusType::Pure) {
369-
inTiming.busType = I3C_PURE_I3C_BUS;
370-
inTiming.i2cODFreq = 0U;
371-
} else {
372-
inTiming.busType = I3C_MIXED_BUS;
373-
inTiming.i2cODFreq = _mixedBusOdFreq;
374-
}
375-
376-
if (I3C_CtrlTimingComputation(&inTiming, &outCtrl) != SUCCESS) {
377-
result = -1;
378-
} else if (HAL_I3C_Ctrl_BusCharacteristicConfig(&_hi3c, &outCtrl) != HAL_OK) {
379-
result = -1;
380-
} else {
381-
result = 0;
382-
}
383389
}
384390
}
385391

@@ -1858,6 +1864,73 @@ void I3CBus::handleHalNotify(uint32_t eventId)
18581864
}
18591865
}
18601866

1867+
// ============================================================================
1868+
// Clock helpers
1869+
// ============================================================================
1870+
uint32_t I3CBus::getPeripheralClockFreq() const
1871+
{
1872+
uint32_t srcFreq = 0U;
1873+
1874+
#if defined(I3C1)
1875+
if (_instance == I3C1) {
1876+
srcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I3C1);
1877+
}
1878+
#endif
1879+
1880+
#if defined(I3C2)
1881+
if (_instance == I3C2) {
1882+
srcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I3C2);
1883+
}
1884+
#endif
1885+
1886+
return srcFreq;
1887+
}
1888+
1889+
bool I3CBus::buildControllerTiming(uint32_t freq, LL_I3C_CtrlBusConfTypeDef &outCtrl) const
1890+
{
1891+
bool result = false;
1892+
uint32_t srcFreq = getPeripheralClockFreq();
1893+
1894+
if (srcFreq != 0U) {
1895+
I3C_CtrlTimingTypeDef inTiming {};
1896+
1897+
inTiming.clockSrcFreq = srcFreq;
1898+
inTiming.i3cPPFreq = (freq == 0U) ? 1000000U : freq;
1899+
inTiming.dutyCycle = 50U;
1900+
1901+
if (_busType == I3CBusType::Pure) {
1902+
inTiming.busType = I3C_PURE_I3C_BUS;
1903+
inTiming.i2cODFreq = 0U;
1904+
} else {
1905+
inTiming.busType = I3C_MIXED_BUS;
1906+
inTiming.i2cODFreq = _mixedBusOdFreq;
1907+
}
1908+
1909+
if (I3C_CtrlTimingComputation(&inTiming, &outCtrl) == SUCCESS) {
1910+
result = true;
1911+
}
1912+
}
1913+
1914+
return result;
1915+
}
1916+
1917+
bool I3CBus::buildTargetTiming(LL_I3C_TgtBusConfTypeDef &outTgt) const
1918+
{
1919+
bool result = false;
1920+
uint32_t srcFreq = getPeripheralClockFreq();
1921+
1922+
if (srcFreq != 0U) {
1923+
I3C_TgtTimingTypeDef inTiming {};
1924+
inTiming.clockSrcFreq = srcFreq;
1925+
1926+
if (I3C_TgtTimingComputation(&inTiming, &outTgt) == SUCCESS) {
1927+
result = true;
1928+
}
1929+
}
1930+
1931+
return result;
1932+
}
1933+
18611934
// ============================================================================
18621935
// IRQ handlers
18631936
// ============================================================================

‎libraries/I3C/src/I3C.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,13 @@ class I3CBus {
525525
static uint32_t bigToLittle32(uint32_t x);
526526
static uint64_t extractPid48FromEntdaaPayload(uint64_t payload);
527527

528+
// ------------------------------------------------------------------------
529+
// Clock helpers
530+
// ------------------------------------------------------------------------
531+
uint32_t getPeripheralClockFreq() const;
532+
bool buildControllerTiming(uint32_t freq, LL_I3C_CtrlBusConfTypeDef &outCtrl) const;
533+
bool buildTargetTiming(LL_I3C_TgtBusConfTypeDef &outTgt) const;
534+
528535
// ------------------------------------------------------------------------
529536
// Internal state
530537
// ------------------------------------------------------------------------

0 commit comments

Comments
 (0)