1 /*
2 * Copyright 2020, 2022-2024 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "fsl_component_i3c_adapter.h"
8 #include "fsl_i3c.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13 #define I3C_TIME_OUT_INDEX 100000000U
14
15 /* I3C master adapter internal resource*/
16 typedef struct _i3c_master_adapter_private
17 {
18 uint8_t devCount;
19 i3c_ccc_dev_t *devList;
20 } i3c_master_adapter_private_t;
21
22 /*******************************************************************************
23 * Prototypes
24 ******************************************************************************/
25 static status_t I3C_MasterAdapterInit(i3c_device_t *master);
26 static status_t I3C_MasterAdapterProcessDAA(i3c_device_t *master);
27 static status_t I3C_MasterAdapterTransmitCCC(i3c_device_t *master, i3c_ccc_cmd_t *cmd);
28 static status_t I3C_MasterAdapterDoI3CTransfer(i3c_device_t *device, i3c_bus_transfer_t *xfer);
29 static status_t I3C_MasterAdapterDoI2CTransfer(i2c_device_t *device, i3c_bus_transfer_t *xfer);
30 static void I3C_SlaveAdapterRequestMastership(i3c_device_t *dev);
31 static void I3C_SlaveAdapterRequestHotJoin(i3c_device_t *dev);
32 static status_t I3C_SlaveAdapterInit(i3c_device_t *dev);
33 static status_t I3C_MasterAdapterHandOffMasterShip(i3c_device_t *master, uint8_t slaveAddr);
34 static void I3C_MasterAdapterTakeOverMasterShip(i3c_device_t *master);
35 static void I3C_SlaveAdapterRequestIBI(i3c_device_t *dev, void *data, size_t dataSize);
36 static void I3C_MasterAdapterRegisterIBI(i3c_device_t *master, uint8_t ibiAddress);
37 static void i3c_master_ibi_callback(I3C_Type *base,
38 i3c_master_handle_t *handle,
39 i3c_ibi_type_t ibiType,
40 i3c_ibi_state_t ibiState);
41 static void i3c_master_callback(I3C_Type *base, i3c_master_handle_t *handle, status_t status, void *userData);
42 static void i3c_slave2master_callback(I3C_Type *base, void *userData);
43 /*******************************************************************************
44 * Variables
45 ******************************************************************************/
46
47 static volatile bool g_masterCompletionFlag = false;
48 static volatile bool g_ibiWonFlag = false;
49 static volatile status_t g_completionStatus = kStatus_Success;
50 static volatile bool g_transferPolling = false;
51
52 const i3c_device_hw_ops_t master_ops = {.Init = I3C_MasterAdapterInit,
53 .Deinit = NULL,
54 .ProceedDAA = I3C_MasterAdapterProcessDAA,
55 .CheckSupportCCC = NULL,
56 .TransmitCCC = I3C_MasterAdapterTransmitCCC,
57 .DoI3CTransfer = I3C_MasterAdapterDoI3CTransfer,
58 .DoI2CTransfer = I3C_MasterAdapterDoI2CTransfer,
59 .HotJoin = I3C_SlaveAdapterRequestHotJoin,
60 .RequestMastership = I3C_SlaveAdapterRequestMastership,
61 .RegisterIBI = I3C_MasterAdapterRegisterIBI,
62 .RequestIBI = I3C_SlaveAdapterRequestIBI};
63
64 const i3c_device_hw_ops_t slave_ops = {.Init = I3C_SlaveAdapterInit,
65 .Deinit = NULL,
66 .ProceedDAA = NULL,
67 .CheckSupportCCC = NULL,
68 .TransmitCCC = NULL,
69 .DoI3CTransfer = NULL,
70 .DoI2CTransfer = NULL,
71 .RegisterIBI = NULL,
72 .HotJoin = I3C_SlaveAdapterRequestHotJoin,
73 .RequestMastership = I3C_SlaveAdapterRequestMastership,
74 .RequestIBI = I3C_SlaveAdapterRequestIBI};
75 static const i3c_master_transfer_callback_t masterCallback = {.slave2Master = i3c_slave2master_callback,
76 .ibiCallback = i3c_master_ibi_callback,
77 .transferComplete = i3c_master_callback};
78
79 /*******************************************************************************
80 * Code
81 ******************************************************************************/
82 #define I3C_SLAVELIST_MAX_LEN 50U
83 #define I3C_MASTER_IBI_BUFF_SIZE 50U
84
i3c_secondarymaster_callback(I3C_Type * base,i3c_slave_transfer_t * xfer,void * userData)85 static void i3c_secondarymaster_callback(I3C_Type *base, i3c_slave_transfer_t *xfer, void *userData)
86 {
87 i3c_device_t *dev = (i3c_device_t *)userData;
88 i3c_device_control_info_t *devControlInfo = dev->devControlInfo;
89 i3c_master_adapter_private_t *masterPrivate = (i3c_master_adapter_private_t *)devControlInfo->privateData;
90 switch ((uint32_t)xfer->event)
91 {
92 case (uint32_t)kI3C_SlaveReceivedCCCEvent:
93 if (0UL != (base->SDATACTRL & I3C_SDATACTRL_RXCOUNT_MASK))
94 {
95 uint8_t cmdID = (uint8_t)(base->SRDATAB & I3C_SRDATAB_DATA0_MASK);
96 /* DEFSLVLIST command */
97 if (cmdID == 0x08U)
98 {
99 xfer->rxData = (uint8_t *)masterPrivate->devList;
100 xfer->rxDataSize = I3C_SLAVELIST_MAX_LEN;
101 }
102 }
103 break;
104
105 case (uint32_t)kI3C_SlaveCompletionEvent:
106 if (xfer->rxData != NULL)
107 {
108 uint8_t *pDevList = (uint8_t *)masterPrivate->devList;
109 masterPrivate->devCount = pDevList[0];
110 masterPrivate->devList = (i3c_ccc_dev_t *)(void *)&pDevList[1];
111 }
112 break;
113
114 case (uint32_t)kI3C_SlaveTransmitEvent:
115 case (uint32_t)kI3C_SlaveReceiveEvent:
116 case (uint32_t)kI3C_SlaveRequestSentEvent:
117 break;
118
119 default:
120 assert(false);
121 break;
122 }
123 }
124
i3c_master_ibi_callback(I3C_Type * base,i3c_master_handle_t * handle,i3c_ibi_type_t ibiType,i3c_ibi_state_t ibiState)125 static void i3c_master_ibi_callback(I3C_Type *base,
126 i3c_master_handle_t *handle,
127 i3c_ibi_type_t ibiType,
128 i3c_ibi_state_t ibiState)
129 {
130 g_transferPolling = true;
131 i3c_device_t *master = (i3c_device_t *)handle->userData;
132 switch (ibiType)
133 {
134 case kI3C_IbiNormal:
135 if (ibiState == kI3C_IbiDataBuffNeed)
136 {
137 handle->ibiBuff = malloc(I3C_MASTER_IBI_BUFF_SIZE);
138 }
139 else
140 {
141 /* Handle ibi data*/
142 void *ibiData = malloc(handle->ibiPayloadSize);
143 (void)memcpy(ibiData, (void *)handle->ibiBuff, handle->ibiPayloadSize);
144 (void)I3C_BusMasterHandleIBI(master, handle->ibiAddress, ibiData, handle->ibiPayloadSize);
145 free(ibiData);
146 }
147 break;
148
149 case kI3C_IbiMasterRequest:
150 if (ibiState == kI3C_IbiAckNackPending)
151 {
152 I3C_MasterEmitIBIResponse(base, kI3C_IbiRespAck);
153 }
154 else
155 {
156 (void)I3C_MasterAdapterHandOffMasterShip(master, handle->ibiAddress);
157 }
158 break;
159
160 case kI3C_IbiHotJoin:
161 (void)I3C_BusMasterDoDAA(master);
162 break;
163
164 default:
165 assert(false);
166 break;
167 }
168 g_transferPolling = false;
169 }
170
i3c_slave2master_callback(I3C_Type * base,void * userData)171 static void i3c_slave2master_callback(I3C_Type *base, void *userData)
172 {
173 i3c_device_t *master = (i3c_device_t *)userData;
174 I3C_MasterAdapterTakeOverMasterShip(master);
175 }
176
i3c_master_callback(I3C_Type * base,i3c_master_handle_t * handle,status_t status,void * userData)177 static void i3c_master_callback(I3C_Type *base, i3c_master_handle_t *handle, status_t status, void *userData)
178 {
179 /* Signal transfer success when received success status. */
180 if (status == kStatus_Success)
181 {
182 g_masterCompletionFlag = true;
183 }
184
185 if (status == kStatus_I3C_IBIWon)
186 {
187 g_ibiWonFlag = true;
188 }
189
190 g_completionStatus = status;
191 }
192
I3C_MasterAdapterInit(i3c_device_t * master)193 static status_t I3C_MasterAdapterInit(i3c_device_t *master)
194 {
195 assert(master != NULL);
196 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
197 i3c_bus_t *bus = master->bus;
198 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
199
200 I3C_Type *base = masterResource->base;
201 i3c_master_transfer_mode_t transMode = masterResource->transMode;
202 i3c_master_adapter_private_t *masterPrivate;
203
204 i3c_config_t masterConfig;
205 I3C_GetDefaultConfig(&masterConfig);
206 masterConfig.baudRate_Hz.i2cBaud = bus->i2cBaudRate;
207 masterConfig.baudRate_Hz.i3cPushPullBaud = bus->i3cPushPullBaudRate;
208 masterConfig.baudRate_Hz.i3cOpenDrainBaud = bus->i3cOpenDrainBaudRate;
209 masterConfig.enableOpenDrainStop = false;
210 masterConfig.masterDynamicAddress = master->info.dynamicAddr;
211 masterConfig.maxWriteLength = master->info.maxWriteLength;
212 masterConfig.maxReadLength = master->info.maxReadLength;
213 masterConfig.staticAddr = master->info.staticAddr;
214 masterConfig.vendorID = master->info.vendorID;
215 masterConfig.partNumber = master->info.partNumber;
216 masterConfig.dcr = master->info.dcr;
217 masterConfig.bcr = master->info.bcr;
218 masterConfig.hdrMode = master->info.hdrMode;
219 #if !(defined(FSL_FEATURE_I3C_HAS_NO_SCONFIG_BAMATCH) && FSL_FEATURE_I3C_HAS_NO_SCONFIG_BAMATCH)
220 masterConfig.slowClock_Hz = masterResource->slowClockInHz;
221 #endif
222
223 masterPrivate = malloc(sizeof(i3c_master_adapter_private_t));
224 masterControlInfo->privateData = masterPrivate;
225
226 /* Master is capable of working as master but work as slave for now */
227 if (masterControlInfo->isSecondary)
228 {
229 masterConfig.enableMaster = kI3C_MasterCapable;
230 masterConfig.enableSlave = true;
231 masterPrivate->devList = malloc(I3C_SLAVELIST_MAX_LEN);
232 masterPrivate->devCount = 0U;
233 (void)memset((void *)masterPrivate->devList, 0, I3C_SLAVELIST_MAX_LEN);
234 }
235 else
236 {
237 masterConfig.enableMaster = kI3C_MasterOn;
238 masterConfig.enableSlave = false;
239 }
240
241 I3C_Init(base, &masterConfig, masterResource->clockInHz);
242
243 if (transMode == kI3C_MasterTransferInterruptMode)
244 {
245 i3c_master_handle_t *g_i3c_m_handle = malloc(sizeof(i3c_master_handle_t));
246 I3C_MasterTransferCreateHandle(base, g_i3c_m_handle, &masterCallback, master);
247 }
248
249 status_t result = kStatus_Success;
250
251 if (masterControlInfo->isSecondary)
252 {
253 /* Create slave handle. */
254 i3c_slave_handle_t *g_i3c_s_handle = malloc(sizeof(*g_i3c_s_handle));
255 I3C_SlaveTransferCreateHandle(base, g_i3c_s_handle, i3c_secondarymaster_callback, master);
256
257 /* Start slave non-blocking transfer. */
258 result =
259 I3C_SlaveTransferNonBlocking(base, g_i3c_s_handle,
260 ((uint32_t)kI3C_SlaveCompletionEvent | (uint32_t)kI3C_SlaveReceivedCCCEvent |
261 (uint32_t)kI3C_SlaveRequestSentEvent));
262 I3C_SlaveDisableInterrupts(base, (uint32_t)kI3C_SlaveTxReadyFlag);
263 }
264 return result;
265 }
266
I3C_MasterAdapterProcessDAA(i3c_device_t * master)267 static status_t I3C_MasterAdapterProcessDAA(i3c_device_t *master)
268 {
269 assert(master != NULL);
270 status_t result = kStatus_Success;
271 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
272 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
273 I3C_Type *base = masterResource->base;
274 uint8_t rxBuffer[8] = {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
275 i3c_bus_t *i3cBus = master->bus;
276 bool mctrlDone = false;
277 uint8_t rxSize = 0;
278 uint32_t errStatus;
279 uint32_t status;
280 size_t rxCount;
281
282 /* Return an error if the bus is already in use not by us. */
283 result = I3C_CheckForBusyBus(base);
284 if (kStatus_Success != result)
285 {
286 return result;
287 }
288
289 /* Clear all flags. */
290 I3C_MasterClearErrorStatusFlags(base, (uint32_t)kI3C_MasterAllErrorFlags);
291 I3C_MasterClearStatusFlags(base, (uint32_t)kI3C_MasterClearFlags);
292
293 /* Disable I3C IRQ sources while we configure stuff. */
294 uint32_t enabledInts = I3C_MasterGetEnabledInterrupts(base);
295 I3C_MasterDisableInterrupts(base, enabledInts);
296
297 /* Emit process DAA */
298 I3C_MasterEmitRequest(base, kI3C_RequestProcessDAA);
299
300 do
301 {
302 status = I3C_MasterGetStatusFlags(base);
303
304 /* Check for error flags. */
305 errStatus = I3C_MasterGetErrorStatusFlags(base);
306 result = I3C_MasterCheckAndClearError(base, errStatus);
307 if (kStatus_Success != result)
308 {
309 return result;
310 }
311
312 if ((!mctrlDone) || (rxSize < 8U))
313 {
314 I3C_MasterGetFifoCounts(base, &rxCount, NULL);
315 while (rxCount-- != 0U)
316 {
317 rxBuffer[rxSize++] = (uint8_t)(base->MRDATAB & I3C_MRDATAB_VALUE_MASK);
318 }
319
320 if ((status & (uint32_t)kI3C_MasterControlDoneFlag) != 0U)
321 {
322 I3C_MasterClearStatusFlags(base, (uint32_t)kI3C_MasterControlDoneFlag);
323 mctrlDone = true;
324 }
325 }
326 else if ((I3C_MasterGetState(base) == kI3C_MasterStateDaa) &&
327 (0UL != (I3C_MasterGetStatusFlags(base) & (uint32_t)kI3C_MasterBetweenFlag)))
328 {
329 uint8_t validAddr = I3C_BusGetValidAddrSlot(i3cBus, 0x0);
330 if (validAddr < I3C_BUS_MAX_ADDR)
331 {
332 /* Assign the dynamic address. */
333 base->MWDATAB = validAddr;
334 /* Emit process DAA again. */
335 I3C_MasterEmitRequest(base, kI3C_RequestProcessDAA);
336
337 i3c_device_t *newI3CDev = malloc(sizeof(i3c_device_t));
338 (void)memset(newI3CDev, 0, sizeof(i3c_device_t));
339 newI3CDev->info.dynamicAddr = validAddr;
340 newI3CDev->info.vendorID = (((uint16_t)rxBuffer[0] << 8U | (uint16_t)rxBuffer[1]) & 0xFFFEU) >> 1U;
341 newI3CDev->info.partNumber = ((uint32_t)rxBuffer[2] << 24U | (uint32_t)rxBuffer[3] << 16U |
342 (uint32_t)rxBuffer[4] << 8U | (uint32_t)rxBuffer[5]);
343 newI3CDev->info.bcr = rxBuffer[6];
344 newI3CDev->info.dcr = rxBuffer[7];
345 I3C_BusAddI3CDev(i3cBus, newI3CDev);
346
347 /* Ready to handle next device. */
348 mctrlDone = false;
349 rxSize = 0;
350 }
351 else
352 {
353 return kStatus_I3CBus_AddrSlotInvalid;
354 }
355 }
356 else
357 {
358 /* Intentional empty */
359 }
360 } while ((status & (uint32_t)kI3C_MasterCompleteFlag) != (uint32_t)kI3C_MasterCompleteFlag);
361
362 I3C_MasterClearStatusFlags(base, (uint32_t)kI3C_MasterCompleteFlag);
363
364 /* Enable I3C IRQ sources while we configure stuff. */
365 I3C_MasterEnableInterrupts(base, enabledInts);
366
367 return kStatus_Success;
368 }
369
I3CMasterAdapterTransfer(I3C_Type * base,i3c_master_transfer_t * xfer,i3c_master_transfer_mode_t transMode)370 static status_t I3CMasterAdapterTransfer(I3C_Type *base,
371 i3c_master_transfer_t *xfer,
372 i3c_master_transfer_mode_t transMode)
373 {
374 g_ibiWonFlag = false;
375 g_masterCompletionFlag = false;
376 uint32_t timeout = 0U;
377 status_t result = kStatus_Success;
378 g_completionStatus = kStatus_Success;
379
380 /*TODO: wait for module idle */
381 if (g_transferPolling == true)
382 {
383 result = I3C_MasterTransferBlocking(base, xfer);
384 }
385 else
386 {
387 void *handle = s_i3cMasterHandle[I3C_GetInstance(base)];
388
389 if (transMode == kI3C_MasterTransferInterruptMode)
390 {
391 result = I3C_MasterTransferNonBlocking(base, handle, xfer);
392 if (kStatus_Success != result)
393 {
394 return result;
395 }
396
397 /* Wait for transfer completed. */
398 while (!g_masterCompletionFlag)
399 {
400 timeout++;
401 __NOP();
402 if (g_ibiWonFlag)
403 {
404 break;
405 }
406 else if ((g_completionStatus != kStatus_Success) || (timeout > I3C_TIME_OUT_INDEX))
407 {
408 break;
409 }
410 else
411 {
412 /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */
413 }
414 }
415
416 result = g_completionStatus;
417 }
418
419 if (timeout == I3C_TIME_OUT_INDEX)
420 {
421 result = kStatus_I3CBus_MasterTransTimeout;
422 }
423 }
424
425 return result;
426 }
I3C_MasterAdapterTransmitCCC(i3c_device_t * master,i3c_ccc_cmd_t * cmd)427 static status_t I3C_MasterAdapterTransmitCCC(i3c_device_t *master, i3c_ccc_cmd_t *cmd)
428 {
429 assert(master != NULL);
430 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
431 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
432 I3C_Type *base = masterResource->base;
433 i3c_master_transfer_mode_t transMode = masterResource->transMode;
434 status_t result = kStatus_Success;
435
436 i3c_master_transfer_t xfer;
437 (void)memset(&xfer, 0, sizeof(xfer));
438
439 if (cmd->destAddr == I3C_BUS_BROADCAST_ADDR)
440 {
441 xfer.slaveAddress = I3C_BUS_BROADCAST_ADDR;
442 xfer.subaddress = cmd->cmdId;
443 xfer.subaddressSize = 1U;
444 xfer.data = cmd->data;
445 xfer.dataSize = cmd->dataSize;
446 xfer.direction = cmd->isRead ? kI3C_Read : kI3C_Write;
447 xfer.busType = kI3C_TypeI3CSdr;
448 xfer.flags = (uint32_t)kI3C_TransferDisableRxTermFlag;
449 result = I3CMasterAdapterTransfer(base, &xfer, transMode);
450 if (result != kStatus_Success)
451 {
452 return result;
453 }
454 }
455 else
456 {
457 xfer.slaveAddress = I3C_BUS_BROADCAST_ADDR;
458 xfer.data = &cmd->cmdId;
459 xfer.dataSize = 1U;
460 xfer.direction = kI3C_Write;
461 xfer.busType = kI3C_TypeI3CSdr;
462 xfer.flags = (uint32_t)kI3C_TransferNoStopFlag;
463 result = I3CMasterAdapterTransfer(base, &xfer, transMode);
464 if (result != kStatus_Success)
465 {
466 return result;
467 }
468
469 xfer.slaveAddress = cmd->destAddr;
470 xfer.data = cmd->data;
471 xfer.dataSize = cmd->dataSize;
472 xfer.direction = cmd->isRead ? kI3C_Read : kI3C_Write;
473 xfer.busType = kI3C_TypeI3CSdr;
474 xfer.flags = (uint32_t)kI3C_TransferRepeatedStartFlag | (uint32_t)kI3C_TransferDisableRxTermFlag;
475 result = I3CMasterAdapterTransfer(base, &xfer, transMode);
476 if (result != kStatus_Success)
477 {
478 return result;
479 }
480 }
481
482 return result;
483 }
484
I3C_MasterAdapterDoI3CTransfer(i3c_device_t * device,i3c_bus_transfer_t * xfer)485 static status_t I3C_MasterAdapterDoI3CTransfer(i3c_device_t *device, i3c_bus_transfer_t *xfer)
486 {
487 assert(device != NULL);
488 i3c_bus_t *bus = device->bus;
489 i3c_device_t *master = (i3c_device_t *)bus->currentMaster;
490 assert(master != NULL);
491
492 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
493 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
494 I3C_Type *base = masterResource->base;
495 i3c_master_transfer_mode_t transMode = masterResource->transMode;
496
497 i3c_master_transfer_t masterXfer;
498 (void)memset(&masterXfer, 0, sizeof(masterXfer));
499
500 masterXfer.slaveAddress = device->info.dynamicAddr;
501 masterXfer.subaddress = xfer->regAddr;
502 masterXfer.subaddressSize = xfer->regAddrSize;
503 masterXfer.data = xfer->data;
504 masterXfer.dataSize = xfer->dataSize;
505 masterXfer.direction = xfer->isRead ? kI3C_Read : kI3C_Write;
506 masterXfer.busType = kI3C_TypeI3CSdr;
507 masterXfer.flags = (uint32_t)kI3C_TransferDefaultFlag;
508
509 return I3CMasterAdapterTransfer(base, &masterXfer, transMode);
510 }
511
I3C_MasterAdapterDoI2CTransfer(i2c_device_t * device,i3c_bus_transfer_t * xfer)512 static status_t I3C_MasterAdapterDoI2CTransfer(i2c_device_t *device, i3c_bus_transfer_t *xfer)
513 {
514 assert(device != NULL);
515 i3c_bus_t *bus = device->bus;
516 i3c_device_t *master = (i3c_device_t *)bus->currentMaster;
517 assert(master != NULL);
518
519 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
520 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
521 I3C_Type *base = masterResource->base;
522 i3c_master_transfer_mode_t transMode = masterResource->transMode;
523
524 i3c_master_transfer_t masterXfer;
525 (void)memset(&masterXfer, 0, sizeof(masterXfer));
526
527 masterXfer.slaveAddress = device->staticAddr;
528 masterXfer.subaddress = xfer->regAddr;
529 masterXfer.subaddressSize = xfer->regAddrSize;
530 masterXfer.data = xfer->data;
531 masterXfer.dataSize = xfer->dataSize;
532 masterXfer.direction = xfer->isRead ? kI3C_Read : kI3C_Write;
533 masterXfer.busType = kI3C_TypeI2C;
534 masterXfer.flags = (uint32_t)kI3C_TransferDefaultFlag;
535
536 return I3CMasterAdapterTransfer(base, &masterXfer, transMode);
537 }
538
I3C_MasterAdapterTakeOverMasterShip(i3c_device_t * master)539 static void I3C_MasterAdapterTakeOverMasterShip(i3c_device_t *master)
540 {
541 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
542 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
543 I3C_Type *base = masterResource->base;
544 i3c_bus_t *i3cBus = master->bus;
545 i3c_master_adapter_private_t *masterPrivate = (i3c_master_adapter_private_t *)masterControlInfo->privateData;
546
547 uint8_t devCount = masterPrivate->devCount;
548 i3c_ccc_dev_t *devList = masterPrivate->devList;
549
550 /* Register bus devices detected from SLAVE */
551 if ((devCount != 0U) && (devList != NULL))
552 {
553 for (uint8_t i = 0U; i < devCount; i++)
554 {
555 i3c_ccc_dev_t *cccDev = &devList[i];
556 #if defined(I3C_SDYNADDR_DADDR_MASK)
557 if (cccDev->dynamicAddr != (base->SDYNADDR & I3C_SDYNADDR_DADDR_MASK))
558 #else
559 if (cccDev->dynamicAddr != (base->SMAPCTRL0 & I3C_SMAPCTRL0_DA_MASK))
560 #endif
561 {
562 if (cccDev->dynamicAddr != 0U)
563 {
564 i3c_device_t *newI3CDev = malloc(sizeof(i3c_device_t));
565 (void)memset(newI3CDev, 0, sizeof(i3c_device_t));
566
567 newI3CDev->info.dynamicAddr = cccDev->dynamicAddr >> 1U;
568 newI3CDev->info.bcr = cccDev->dcr;
569 newI3CDev->info.dcr = cccDev->dcr;
570 newI3CDev->info.staticAddr = cccDev->staticAddr >> 1U;
571
572 I3C_BusAddI3CDev(i3cBus, newI3CDev);
573 }
574 else
575 {
576 i2c_device_t *newI2CDev = malloc(sizeof(i2c_device_t));
577 (void)memset(newI2CDev, 0, sizeof(i2c_device_t));
578
579 newI2CDev->lvr = cccDev->lvr;
580 newI2CDev->staticAddr = cccDev->staticAddr >> 1U;
581
582 I3C_BusAddI2CDev(i3cBus, newI2CDev);
583 }
584 }
585 else
586 {
587 master->info.dynamicAddr = cccDev->dynamicAddr >> 1U;
588 }
589 }
590 }
591
592 i3cBus->currentMaster = master;
593 masterControlInfo->isSecondary = false;
594
595 /* Clear all flags. */
596 I3C_SlaveClearStatusFlags(base, (uint32_t)kI3C_SlaveClearFlags);
597
598 /* Disable I3C slave IRQ resources */
599 I3C_SlaveDisableInterrupts(base, (uint32_t)kI3C_SlaveAllIrqFlags);
600
601 I3C_MasterEnable(base, kI3C_MasterOn);
602 I3C_SlaveEnable(base, false);
603 }
604
I3C_MasterAdapterHandOffMasterShip(i3c_device_t * master,uint8_t slaveAddr)605 static status_t I3C_MasterAdapterHandOffMasterShip(i3c_device_t *master, uint8_t slaveAddr)
606 {
607 status_t result = kStatus_Success;
608 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
609 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
610 I3C_Type *base = masterResource->base;
611 i3c_bus_t *bus = master->bus;
612
613 /* Disable MR and hotjoin events */
614 result =
615 I3C_BusMasterDisableEvents(master, I3C_BUS_BROADCAST_ADDR, ((uint8_t)kI3C_EventMR | (uint8_t)kI3C_EventHJ));
616 if (result != kStatus_Success)
617 {
618 return result;
619 }
620
621 /* Send device list on bus */
622 result = I3C_BusMasterSendSlavesList(master);
623 if (result != kStatus_Success)
624 {
625 return result;
626 }
627
628 uint8_t accData;
629 i3c_ccc_cmd_t getAccMstCmd = {0};
630
631 getAccMstCmd.isRead = true;
632 getAccMstCmd.cmdId = I3C_BUS_CCC_GETACCMST;
633 getAccMstCmd.destAddr = slaveAddr;
634 getAccMstCmd.data = &accData;
635 getAccMstCmd.dataSize = 1;
636
637 result = I3C_MasterAdapterTransmitCCC(master, &getAccMstCmd);
638
639 /* Change current master to secondary master */
640 bus->currentMaster = NULL;
641 masterControlInfo->isSecondary = true;
642
643 /* Clear all flags. */
644 I3C_MasterClearStatusFlags(base, (uint32_t)kI3C_MasterClearFlags);
645 I3C_MasterEnable(base, kI3C_MasterCapable);
646 I3C_SlaveEnable(base, true);
647
648 /* Create slave handle. */
649 i3c_slave_handle_t *g_i3c_s_handle = malloc(sizeof(*g_i3c_s_handle));
650 I3C_SlaveTransferCreateHandle(base, g_i3c_s_handle, i3c_secondarymaster_callback, master);
651
652 /* Start slave non-blocking transfer. */
653 result = I3C_SlaveTransferNonBlocking(base, g_i3c_s_handle,
654 ((uint32_t)kI3C_SlaveCompletionEvent | (uint32_t)kI3C_SlaveReceivedCCCEvent));
655 I3C_SlaveDisableInterrupts(base, (uint32_t)kI3C_SlaveTxReadyFlag);
656
657 return result;
658 }
659
I3C_MasterAdapterRegisterIBI(i3c_device_t * master,uint8_t ibiAddress)660 static void I3C_MasterAdapterRegisterIBI(i3c_device_t *master, uint8_t ibiAddress)
661 {
662 i3c_device_control_info_t *masterControlInfo = master->devControlInfo;
663 i3c_master_adapter_resource_t *masterResource = (i3c_master_adapter_resource_t *)masterControlInfo->resource;
664 I3C_Type *base = masterResource->base;
665
666 i3c_register_ibi_addr_t ibiRule;
667 I3C_MasterGetIBIRules(base, &ibiRule);
668 if (ibiRule.ibiHasPayload)
669 {
670 ibiRule.ibiHasPayload = true;
671 }
672
673 for (uint32_t count = 0; count < ARRAY_SIZE(ibiRule.address); count++)
674 {
675 if (0U == ibiRule.address[count])
676 {
677 ibiRule.address[count] = ibiAddress;
678 break;
679 }
680 }
681
682 I3C_MasterRegisterIBI(base, &ibiRule);
683 }
684
I3C_SlaveAdapterInit(i3c_device_t * dev)685 static status_t I3C_SlaveAdapterInit(i3c_device_t *dev)
686 {
687 assert(dev != NULL);
688
689 i3c_device_control_info_t *devControlInfo = dev->devControlInfo;
690 i3c_device_information_t *devInfo = &dev->info;
691 i3c_device_adapter_resource_t *devResource = (i3c_device_adapter_resource_t *)devControlInfo->resource;
692
693 I3C_Type *base = devResource->base;
694
695 i3c_slave_config_t slaveConfig;
696 I3C_SlaveGetDefaultConfig(&slaveConfig);
697 slaveConfig.staticAddr = devInfo->staticAddr;
698 slaveConfig.dcr = devInfo->dcr;
699 slaveConfig.bcr = devInfo->bcr;
700 slaveConfig.partNumber = devInfo->partNumber;
701 slaveConfig.vendorID = devInfo->vendorID;
702 slaveConfig.offline = false;
703
704 I3C_SlaveInit(base, &slaveConfig, devResource->clockInHz);
705
706 /* Create slave handle. */
707 i3c_slave_handle_t *g_i3c_s_handle = malloc(sizeof(*g_i3c_s_handle));
708 I3C_SlaveTransferCreateHandle(base, g_i3c_s_handle, devResource->callback, dev);
709
710 /* Start slave non-blocking transfer. */
711 status_t result = kStatus_Success;
712 result = I3C_SlaveTransferNonBlocking(base, g_i3c_s_handle, (uint32_t)kI3C_SlaveCompletionEvent);
713
714 return result;
715 }
716
I3C_SlaveAdapterRequestHotJoin(i3c_device_t * dev)717 static void I3C_SlaveAdapterRequestHotJoin(i3c_device_t *dev)
718 {
719 assert(dev != NULL);
720
721 i3c_device_control_info_t *devControlInfo = dev->devControlInfo;
722 i3c_device_adapter_resource_t *devResource = (i3c_device_adapter_resource_t *)devControlInfo->resource;
723
724 I3C_Type *base = devResource->base;
725
726 I3C_SlaveRequestEvent(base, kI3C_SlaveEventHotJoinReq);
727 }
728
I3C_SlaveAdapterRequestMastership(i3c_device_t * dev)729 static void I3C_SlaveAdapterRequestMastership(i3c_device_t *dev)
730 {
731 assert(dev != NULL);
732
733 i3c_device_control_info_t *devControlInfo = dev->devControlInfo;
734 i3c_device_adapter_resource_t *devResource = (i3c_device_adapter_resource_t *)devControlInfo->resource;
735
736 I3C_Type *base = devResource->base;
737
738 I3C_SlaveRequestEvent(base, kI3C_SlaveEventMasterReq);
739 }
740
I3C_SlaveAdapterRequestIBI(i3c_device_t * dev,void * data,size_t dataSize)741 static void I3C_SlaveAdapterRequestIBI(i3c_device_t *dev, void *data, size_t dataSize)
742 {
743 assert(dev != NULL);
744
745 i3c_device_control_info_t *devControlInfo = dev->devControlInfo;
746 i3c_device_adapter_resource_t *devResource = (i3c_device_adapter_resource_t *)devControlInfo->resource;
747
748 I3C_Type *base = devResource->base;
749
750 if (data != NULL)
751 {
752 I3C_SlaveRequestIBIWithData(base, (uint8_t *)data, dataSize);
753 }
754 else
755 {
756 I3C_SlaveRequestEvent(base, kI3C_SlaveEventIBI);
757 }
758 }
759