1 /**
2 **********************************************************************************************************************
3 * @file stm32h5xx_hal_i3c.c
4 * @author MCD Application Team
5 * @brief I3C HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Improvement Inter Integrated Circuit (I3C) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral State and Errors functions
11 *
12 **********************************************************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2023 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 **********************************************************************************************************************
23 @verbatim
24 ======================================================================================================================
25 ##### How to use this driver #####
26 ======================================================================================================================
27 [..]
28 The I3C HAL driver can be used as follows:
29
30 (#) Declare a I3C_HandleTypeDef handle structure, for example:
31 I3C_HandleTypeDef hi3c;
32
33 (#) Declare a I3C_XferTypeDef transfer descriptor structure, for example:
34 I3C_XferTypeDef ContextBuffers;
35
36 (#)Initialize the I3C low level resources by implementing the HAL_I3C_MspInit() API:
37 (##) Enable the I3Cx interface clock
38 (##) I3C pins configuration
39 (+++) Enable the clock for the I3C GPIOs
40 (+++) Configure I3C pins as alternate function push-pull with no-pull
41 (##) NVIC configuration if you need to use interrupt process
42 (+++) Configure the I3Cx interrupt priority
43 (+++) Enable the NVIC I3C IRQ Channel
44 (##) DMA Configuration if you need to use DMA process
45 (+++) Declare a DMA_HandleTypeDef handle structure for
46 the Command Common Code (CCC) management channel
47 (+++) Declare a DMA_HandleTypeDef handle structure for
48 the transmit channel
49 (+++) Declare a DMA_HandleTypeDef handle structure for
50 the receive channel
51 (+++) Declare a DMA_HandleTypeDef handle structure for
52 the status channel
53 (+++) Enable the DMAx interface clock
54 (+++) Configure the DMA handle parameters
55 (+++) Configure the DMA Command Common Code (CCC) channel
56 (+++) Configure the DMA Tx channel
57 (+++) Configure the DMA Rx channel
58 (+++) Configure the DMA Status channel
59 (+++) Associate the initialized DMA handle to the hi3c DMA CCC, Tx, Rx or Status handle as necessary
60 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
61 the DMA CCC, Tx, Rx or Status instance
62
63 (#) Configure the HAL I3C Communication Mode as Controller or Target in the hi3c Init structure.
64
65 (#) Configure the Controller Communication Bus characterics for Controller mode.
66 This mean, configure the parameters SDAHoldTime, WaitTime, SCLPPLowDuration,
67 SCLI3CHighDuration, SCLODLowDuration, SCLI2CHighDuration, BusFreeDuration,
68 BusIdleDuration in the LL_I3C_CtrlBusConfTypeDef structure through h3c Init structure.
69
70 (#) Configure the Target Communication Bus characterics for Target mode.
71 This mean, configure the parameter BusAvailableDuration in the LL_I3C_TgtBusConfTypeDef structure
72 through h3c Init structure.
73
74 All these parameters for Controller or Target can be configured directly in user code or
75 by using CubeMx generation.
76 To help the computation of the different parameters, the recommendation is to use CubeMx.
77
78 Those parameters can be modified after the hi3c initialization by using
79 HAL_I3C_Ctrl_BusCharacteristicConfig() for controller and
80 HAL_I3C_Tgt_BusCharacteristicConfig() for target.
81
82 (#) Initialize the I3C registers by calling the HAL_I3C_Init(), configures also the low level Hardware
83 (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I3C_MspInit(&hi3c) API.
84
85 (#) Configure the different FIFO parameters in I3C_FifoConfTypeDef structure as RxFifoThreshold, TxFifoThreshold
86 for Controller or Target mode.
87 And enable/disable the Control or Status FIFO only for Controller Mode.
88 Use HAL_I3C_SetConfigFifo() function to finalize the configuration, and HAL_I3C_GetConfigFifo() to retrieve
89 FIFO configuration.
90 Possibility to clear the FIFO configuration by using HAL_I3C_ClearConfigFifo() which reset the configuration
91 FIFO to their default hardware value
92
93 (#) Configure the different additional Controller configuration in I3C_CtrlConfTypeDef structure as DynamicAddr,
94 StallTime, HotJoinAllowed, ACKStallState, CCCStallState, TxStallState, RxStallState, HighKeeperSDA.
95 Use HAL_I3C_Ctrl_Config() function to finalize the Controller configuration.
96
97 (#) Configure the different additional Target configuration in I3C_TgtConfTypeDef structure as Identifier,
98 MIPIIdentifier, CtrlRoleRequest, HotJoinRequest, IBIRequest, IBIPayload, IBIPayloadSize, MaxReadDataSize,
99 MaxWriteDataSize, CtrlCapability, GroupAddrCapability, DataTurnAroundDuration, MaxReadTurnAround,
100 MaxDataSpeed, MaxSpeedLimitation, HandOffActivityState, HandOffDelay, PendingReadMDB.
101 Use HAL_I3C_Tgt_Config() function to finalize the Target configuration.
102
103 (#) Before initiate any IO operation, the application must launch an assignment of the different
104 Target dynamic address by using HAL_I3C_Ctrl_DynAddrAssign() in polling mode or
105 HAL_I3C_Ctrl_DynAddrAssign_IT() in interrupt mode.
106 This procedure is named Enter Dynamic Address Assignment (ENTDAA CCC command).
107 For the initiation of ENTDAA procedure from the controller, each target connected and powered on the I3C bus
108 must repond to this particular Command Common Code by sending its proper Payload (a amount of 48bits which
109 contain the target characteristics)
110 Each time a target responds to ENTDAA sequence, the application is informed through
111 HAL_I3C_TgtReqDynamicAddrCallback() of the reception of the target paylaod.
112 And then application must send a associated dynamic address through HAL_I3C_Ctrl_SetDynAddr().
113 This procedure in loop automatically in hardware side until a target respond to repeated ENTDAA sequence.
114 The application is informed of the end of the procedure at reception of HAL_I3C_CtrlDAACpltCallback().
115 Then application can easily retrieve ENTDAA payload information through HAL_I3C_Get_ENTDAA_Payload_Info()
116 function.
117 At the end of procedure, the function HAL_I3C_Ctrl_ConfigBusDevices() must be called to store in hardware
118 register part the target capabilities as Dynamic address, IBI support with or without additional data byte,
119 Controller role request support, Controller stop transfer after IBI through I3C_DeviceConfTypeDef structure.
120
121 (#) Other action to be done, before initiate any IO operation, the application must prepare the different frame
122 descriptor with its associated buffer allocation in their side.
123 Configure the different information related to CCC transfer through I3C_CCCTypeDef structure
124 Configure the different information related to Private or I2C transfer through I3C_PrivateTypeDef structure
125 Configure the different buffer pointers and associated size needed for the driver communication
126 through I3C_XferTypeDef structure
127 The I3C_XferTypeDef structure contains different parameters about Control, Status buffer,
128 and Transmit and Receive buffer.
129 Use HAL_I3C_AddDescToFrame() function each time application add a descriptor in the frame before call
130 a Controller IO operation interface
131 One element of the frame descriptor correspond to one frame to manage through IO operation.
132
133 (#) To check if I3C target device is ready for communication, use the function HAL_I3C_Ctrl_IsDeviceI3C_Ready()
134
135 (#) To check if I2C target device is ready for communication, use the function HAL_I3C_Ctrl_IsDeviceI2C_Ready()
136
137 (#) To send a message header {S + 0x7E + W + STOP}, use the function HAL_I3C_Ctrl_GenerateArbitration().
138 (#) To insert a target reset pattern before the STOP of a transmitted frame containing a RSTACT CCC command,
139 the application must enable the reset pattern configuration using HAL_I3C_Ctrl_SetConfigResetPattern()
140 before calling HAL_I3C_Ctrl_TransmitCCC() or HAL_I3C_Ctrl_ReceiveCCC() interfaces.
141
142 To have a standard STOP emitted at the end of a frame containing a RSTACT CCC command, the application must
143 disable the reset pattern configuration using HAL_I3C_Ctrl_SetConfigResetPattern() before calling
144 HAL_I3C_Ctrl_TransmitCCC() or HAL_I3C_Ctrl_ReceiveCCC() interfaces.
145
146 Use HAL_I3C_Ctrl_SetConfigResetPattern() function to configure the insertion of the reset pattern at
147 the end of a Frame, and HAL_I3C_Ctrl_GetConfigResetPattern() to retrieve reset pattern configuration.
148
149 (#) For I3C IO operations, three operation modes are available within this driver :
150
151 *** Polling mode IO operation ***
152 =================================
153 [..]
154 (+) Activate asynchronous event in controller or target mode a Common Command Code in a broadcast
155 or a direct communication in blocking mode using HAL_I3C_Ctrl_TransmitCCC()
156 (+) Transmit in controller mode a Common Command Code in a broadcast or a direct communication in blocking mode
157 using HAL_I3C_Ctrl_TransmitCCC()
158 (+) Receive in controller mode a Common Command Code in a direct communication in blocking mode
159 using HAL_I3C_Ctrl_ReceiveCCC()
160 (+) Transmit in controller mode an amount of private data in an I3C or an I2C communication in blocking mode
161 using HAL_I3C_Ctrl_Transmit()
162 (+) Receive in controller mode an amount of private data in an I3C or an I2C communication in blocking mode
163 using HAL_I3C_Ctrl_Receive()
164 (+) Transmit in target mode an amount of private data in an I3C communication in blocking mode
165 using HAL_I3C_Tgt_Transmit()
166 (+) Receive in target mode an amount of private data in an I3C communication in blocking mode
167 using HAL_I3C_Tgt_Receive()
168 (+) At the end of a transfer, the different FIFO can be flushed if necessary by using HAL_I3C_FlushAllFifo() for
169 flush all the FIFO, or flush individually y using HAL_I3C_FlushTxFifo(), HAL_I3C_FlushRxFifo(),
170 HAL_I3C_FlushControlFifo(), HAL_I3C_FlushStatusFifo().
171 (+) Request a HotJoin in target mode in blocking mode using HAL_I3C_Tgt_HotJoinReq()
172 (+) Request a In Band Interrupt in target mode in blocking mode using HAL_I3C_Tgt_IBIReq()
173 (+) Request a Controller Role in target mode in blocking mode using HAL_I3C_Tgt_ControlRoleReq()
174
175
176 *** DMA and Interrupt mode IO operation ***
177 ===================================
178 [..]
179 (+) Transmit in controller mode a Common Command Code in a broadcast or a direct communication in non-blocking
180 mode using HAL_I3C_Ctrl_TransmitCCC_IT() or HAL_I3C_Ctrl_TransmitCCC_DMA()
181 (+) At transmission end of transfer, HAL_I3C_CtrlTxCpltCallback() is executed and users can
182 add their own code by customization of function pointer HAL_I3C_CtrlTxCpltCallback()
183 (+) Receive in controller mode a Common Command Code in a direct communication in non-blocking
184 mode using HAL_I3C_Ctrl_ReceiveCCC_IT() or HAL_I3C_Ctrl_ReceiveCCC_DMA()
185 (+) At reception end of transfer, HAL_I3C_CtrlRxCpltCallback() is executed and users can
186 add their own code by customization of function pointer HAL_I3C_CtrlRxCpltCallback()
187 (+) Transmit in controller mode an amount of private data in an I3C or an I2C communication in non-blocking mode
188 using HAL_I3C_Ctrl_Transmit_IT() or HAL_I3C_Ctrl_Transmit_DMA()
189 (+) At transmission end of transfer, HAL_I3C_CtrlTxCpltCallback() is executed and users can
190 add their own code by customization of function pointer HAL_I3C_CtrlTxCpltCallback()
191 (+) Receive in controller mode an amount of private data in an I3C or an I2C communication in non-blocking mode
192 using HAL_I3C_Ctrl_Receive_IT() or HAL_I3C_Ctrl_Receive_DMA()
193 (+) At reception end of transfer, HAL_I3C_CtrlRxCpltCallback() is executed and users can
194 add their own code by customization of function pointer HAL_I3C_CtrlRxCpltCallback()
195 (+) Transfer in multiple direction (transmit/receive) in controller mode a Common Command Code in a direct
196 communication or an amount of private data in an I2C or I3C communication in non-blocking mode using
197 HAL_I3C_Ctrl_MultipleTransfer_IT() or HAL_I3C_Ctrl_MultipleTransfer_DMA()
198 (+) At the end of transfer, HAL_I3C_CtrlMultipleXferCpltCallback() is executed and users can
199 add their own code by customization of function pointer HAL_I3C_CtrlMultipleXferCpltCallback()
200 (+) Transmit in target mode an amount of private data in an I3C communication in non-blocking mode
201 using HAL_I3C_Tgt_Transmit_IT() or HAL_I3C_Tgt_Transmit_DMA()
202 (+) At transmission end of transfer, HAL_I3C_TgtTxCpltCallback() is executed and users can
203 add their own code by customization of function pointer HAL_I3C_TgtTxCpltCallback()
204 (+) Receive in target mode an amount of private data in an I3C communication in non-blocking mode
205 using HAL_I3C_Tgt_Receive_IT() or HAL_I3C_Tgt_Receive_DMA()
206 (+) At reception end of transfer, HAL_I3C_TgtRxCpltCallback() is executed and users can
207 add their own code by customization of function pointer HAL_I3C_TgtRxCpltCallback()
208 (+) To treat asynchronous event, HAL_I3C_ActivateNotification() or HAL_I3C_DeactivateNotification() function is
209 used for enable or disable one or more notification related to specific asynchronous event.
210 Each time one or more event detected by hardware the associated HAL_I3C_NotifyCallback() is executed
211 and users can add their own code by customization of function pointer HAL_I3C_NotifyCallback().
212 Then application can easily retrieve some specific associated event data through HAL_I3C_GetCCCInfo() function
213 (+) At the end of a transfer, the different FIFO can be flushed if necessary by using HAL_I3C_FlushAllFifo() for
214 flush all the FIFO, or flush individually y using HAL_I3C_FlushTxFifo(), HAL_I3C_FlushRxFifo(),
215 HAL_I3C_FlushControlFifo(), HAL_I3C_FlushStatusFifo().
216 (+) Request a HotJoin in target mode in non-blocking mode using HAL_I3C_Tgt_HotJoinReq_IT
217 (+) At completion, HAL_I3C_TgtHotJoinCallback() is executed and users can
218 add their own code by customization of function pointer HAL_I3C_TgtHotJoinCallback()
219 (+) Request an In Band Interrupt in target mode in non-blocking mode using HAL_I3C_Tgt_IBIReq_IT()
220 (+) At completion, HAL_I3C_NotifyCallback() is executed and users can
221 add their own code by customization of function pointer HAL_I3C_NotifyCallback()
222 (+) Request a Controller Role in target mode in non-blocking mode using HAL_I3C_Tgt_ControlRoleReq_IT()
223 (+) At completion, HAL_I3C_NotifyCallback() is executed and users can
224 add their own code by customization of function pointer HAL_I3C_NotifyCallback()
225 (+) To manage the wakeup capability, HAL_I3C_ActivateNotification() or HAL_I3C_DeactivateNotification() function
226 is used for enable or disable Wake Up interrupt.
227 At wakeup detection the associated HAL_I3C_NotifyCallback() is executed.
228 (+) In case of transfer Error, HAL_I3C_ErrorCallback() function is executed and users can
229 add their own code by customization of function pointer HAL_I3C_ErrorCallback()
230 (+) Abort an I3C process communication with Interrupt using HAL_I3C_Abort_IT()
231 (+) End of abort process, HAL_I3C_AbortCpltCallback() is executed and users can
232 add their own code by customization of function pointer HAL_I3C_AbortCpltCallback()
233
234
235 *** I3C HAL driver macros list ***
236 ==================================
237 [..]
238 Below the list of most used macros in I3C HAL driver.
239
240 (+) __HAL_I3C_ENABLE: Enable the I3C peripheral
241 (+) __HAL_I3C_DISABLE: Disable the I3C peripheral
242 (+) __HAL_I3C_RESET_HANDLE_STATE: Reset the I3C handle state
243 (+) __HAL_I3C_GET_FLAG: Check whether the specified I3C flag is set or not
244
245 *** Callback registration ***
246 =============================================
247 [..]
248 The compilation flag USE_HAL_I3C_REGISTER_CALLBACKS when set to 1
249 allows the user to configure dynamically the driver callbacks.
250 Use Functions HAL_I3C_RegisterCallback() or HAL_I3C_RegisterNotifyCallback()
251 or HAL_I3C_RegisterTgtReqDynamicAddrCallback() or HAL_I3C_RegisterTgtHotJoinCallback()
252 to register an interrupt callback.
253 [..]
254 Function HAL_I3C_RegisterCallback() allows to register following callbacks:
255 (+) CtrlTxCpltCallback : callback for Controller transmission CCC, I3C private or I2C end of transfer.
256 (+) CtrlRxCpltCallback : callback for Controller reception CCC, I3C private or I2C end of transfer.
257 (+) CtrlMultipleXferCpltCallback : callback for Controller multiple Direct CCC, I3C private or I2C
258 end of transfer.
259 (+) CtrlDAACpltCallback : callback for Controller Enter Dynamic Address Assignment end of transfer.
260 (+) TgtTxCpltCallback : callback for Target transmission I3C private end of transfer.
261 (+) TgtRxCpltCallback : callback for Target reception I3C private end of transfer.
262 (+) ErrorCallback : callback for error detection.
263 (+) AbortCpltCallback : callback for abort completion process.
264 (+) MspInitCallback : callback for Msp Init.
265 (+) MspDeInitCallback : callback for Msp DeInit.
266 This function takes as parameters the HAL peripheral handle, the Callback ID
267 and a pointer to the user callback function.
268 [..]
269 For specific callback NotifyCallback
270 use dedicated register callbacks : HAL_I3C_RegisterNotifyCallback().
271 [..]
272 For specific callback TgtReqDynamicAddrCallback
273 use dedicated register callbacks : HAL_I3C_RegisterTgtReqDynamicAddrCallback().
274 [..]
275 For specific callback TgtHotJoinCallback
276 use dedicated register callbacks : HAL_I3C_RegisterTgtHotJoinCallback().
277 [..]
278 Use function HAL_I3C_UnRegisterCallback to reset a callback to the default
279 weak function.
280 HAL_I3C_UnRegisterCallback takes as parameters the HAL peripheral handle,
281 and the Callback ID.
282 This function allows to reset following callbacks:
283 (+) CtrlTxCpltCallback : callback for Controller transmission CCC, I3C private or I2C end of transfer.
284 (+) CtrlRxCpltCallback : callback for Controller reception CCC, I3C private or I2C end of transfer.
285 (+) CtrlMultipleXferCpltCallback : callback for Controller multiple Direct CCC, I3C private or I2C
286 end of transfer.
287 (+) CtrlDAACpltCallback : callback for Controller Enter Dynamic Address Assignment end of transfer.
288 (+) TgtTxCpltCallback : callback for Target transmission I3C private end of transfer.
289 (+) TgtRxCpltCallback : callback for Target reception I3C private end of transfer.
290 (+) ErrorCallback : callback for error detection.
291 (+) AbortCpltCallback : callback for abort completion process.
292 (+) MspInitCallback : callback for Msp Init.
293 (+) MspDeInitCallback : callback for Msp DeInit.
294 (+) NotifyCallback : callback for Controller and Target notification process.
295 (+) TgtReqDynamicAddrCallback : callback for controller application
296 when a target sent its payload to the controller during Dynamic Address Assignment process.
297 (+) TgtHotJoinCallback : callback for Target Hotjoin completion process.
298 [..]
299 By default, after the HAL_I3C_Init() and when the state is HAL_I3C_STATE_RESET
300 all callbacks are set to the corresponding weak functions:
301 examples HAL_I3C_CtrlTxCpltCallback(), HAL_I3C_CtrlRxCpltCallback().
302 Exception done for MspInit and MspDeInit functions that are
303 reset to the legacy weak functions in the HAL_I3C_Init()/ HAL_I3C_DeInit() only when
304 these callbacks are null (not registered beforehand).
305 If MspInit or MspDeInit are not null, the HAL_I3C_Init()/ HAL_I3C_DeInit()
306 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
307 [..]
308 Callbacks can be registered/unregistered in HAL_I3C_STATE_READY state only.
309 Exception done MspInit/MspDeInit functions that can be registered/unregistered
310 in HAL_I3C_STATE_READY or HAL_I3C_STATE_RESET state,
311 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
312 Then, the user first registers the MspInit/MspDeInit user callbacks
313 using HAL_I3C_RegisterCallback() before calling HAL_I3C_DeInit()
314 or HAL_I3C_Init() function.
315 [..]
316 When the compilation flag USE_HAL_I3C_REGISTER_CALLBACKS is set to 0 or
317 not defined, the callback registration feature is not available and all callbacks
318 are set to the corresponding weak functions.
319
320 [..]
321 (@) You can refer to the I3C HAL driver header file for more useful macros
322
323 @endverbatim
324 **********************************************************************************************************************
325 */
326
327 /* Includes ----------------------------------------------------------------------------------------------------------*/
328 #include "stm32h5xx_hal.h"
329
330 /** @addtogroup STM32H5xx_HAL_Driver
331 * @{
332 */
333
334 /** @defgroup I3C I3C
335 * @brief I3C HAL module driver
336 * @{
337 */
338
339 #ifdef HAL_I3C_MODULE_ENABLED
340
341 /* Private typedef ---------------------------------------------------------------------------------------------------*/
342 /* Private define ----------------------------------------------------------------------------------------------------*/
343 /** @defgroup I3C_Private_Define I3C Private Define
344 * @{
345 */
346
347 /* Private define to centralize the enable/disable of Interrupts */
348 #define I3C_XFER_LISTEN_IT (0x00000001U)
349 #define I3C_XFER_TARGET_TX_IT (0x00000002U)
350 #define I3C_XFER_TARGET_RX_IT (0x00000004U)
351 #define I3C_XFER_DMA (0x00000008U)
352 #define I3C_XFER_TARGET_CTRLROLE (0x00000010U)
353 #define I3C_XFER_TARGET_HOTJOIN (0x00000020U)
354 #define I3C_XFER_TARGET_IBI (0x00000040U)
355 #define I3C_XFER_CONTROLLER_TX_IT (0x00000080U)
356 #define I3C_XFER_CONTROLLER_RX_IT (0x00000100U)
357 #define I3C_XFER_CONTROLLER_RX_CCC_IT (0x00000400U)
358 #define I3C_XFER_CONTROLLER_DAA_IT (0x00001000U)
359
360 /* Private defines for control buffer prior preparation */
361 #define I3C_OPERATION_TYPE_MASK (0x78000000U)
362 #define I3C_RESTART_STOP_MASK (0x80000000U)
363 #define I3C_ARBITRATION_HEADER_MASK (0x00000004U)
364 #define I3C_DEFINE_BYTE_MASK (0x00000001U)
365
366 /* Private define for CCC command */
367 #define I3C_BROADCAST_RSTDAA (0x00000006U)
368 #define I3C_BROADCAST_ENTDAA (0x00000007U)
369
370 /* Private define to split ENTDAA payload */
371 #define I3C_DCR_IN_PAYLOAD_SHIFT 56
372 #define I3C_PID_IN_PAYLOAD_MASK 0xFFFFFFFFFFFFU
373
374 /* Private define to split PID */
375 /* Bits[47:33]: MIPI Manufacturer ID */
376 #define I3C_MIPIMID_PID_SHIFT 33
377 #define I3C_MIPIMID_PID_MASK 0x7FFFU
378
379 /* Bit[32]: Provisioned ID Type Selector */
380 #define I3C_IDTSEL_PID_SHIFT 32
381 #define I3C_IDTSEL_PID_MASK 0x01U
382
383 /* Bits[31:16]: Part ID */
384 #define I3C_PART_ID_PID_SHIFT 16
385 #define I3C_PART_ID_PID_MASK 0xFFFFU
386
387 /* Bits[15:12]: MIPI Instance ID */
388 #define I3C_MIPIID_PID_SHIFT 12
389 #define I3C_MIPIID_PID_MASK 0xFU
390 /**
391 * @}
392 */
393
394 /* Private macro -----------------------------------------------------------------------------------------------------*/
395
396 /** @brief Get Provisioned ID in payload (64bits) receive during ENTDAA procedure.
397 * @param __PAYLOAD__ specifies the Device Characteristics capabilities retrieve during ENTDAA procedure.
398 * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFFFFFF.
399 * @retval The value of PID Return value between Min_Data=0x00 and Max_Data=0xFFFFFFFFFFFF.
400 */
401 #define I3C_GET_PID(__PAYLOAD__) ((uint64_t)(__PAYLOAD__) & I3C_PID_IN_PAYLOAD_MASK)
402
403 /** @brief Get MIPI Manufacturer ID in PID (48bits).
404 * @param __PID__ specifies the Provisioned ID retrieve during ENTDAA procedure.
405 * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFF.
406 * @retval The value of MIPI ID Return value between Min_Data=0x00 and Max_Data=0x7FFF.
407 */
408 #define I3C_GET_MIPIMID(__PID__) ((uint16_t)((uint64_t)(__PID__) >> I3C_MIPIMID_PID_SHIFT) & \
409 I3C_MIPIMID_PID_MASK)
410
411 /** @brief Get Type Selector in PID (48bits).
412 * @param __PID__ specifies the Provisioned ID retrieve during ENTDAA procedure.
413 * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFF.
414 * @retval The value of Type Selector Return 0 or 1.
415 */
416 #define I3C_GET_IDTSEL(__PID__) ((uint8_t)((uint64_t)(__PID__) >> I3C_IDTSEL_PID_SHIFT) & \
417 I3C_IDTSEL_PID_MASK)
418
419 /** @brief Get Part ID in PID (48bits).
420 * @param __PID__ specifies the Provisioned ID retrieve during ENTDAA procedure.
421 * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFF.
422 * @retval The value of Part ID Return value between Min_Data=0x00 and Max_Data=0xFFFF.
423 */
424 #define I3C_GET_PART_ID(__PID__) ((uint16_t)((uint64_t)(__PID__) >> I3C_PART_ID_PID_SHIFT) & \
425 I3C_PART_ID_PID_MASK)
426
427 /** @brief Get Instance ID in PID (48bits).
428 * @param __PID__ specifies the Provisioned ID retrieve during ENTDAA procedure.
429 * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFF.
430 * @retval The value of Instance ID Return value between Min_Data=0x00 and Max_Data=0xF.
431 */
432 #define I3C_GET_MIPIID(__PID__) ((uint8_t)((uint64_t)(__PID__) >> I3C_MIPIID_PID_SHIFT) & \
433 I3C_MIPIID_PID_MASK)
434
435 /** @brief Get Device Characterics in payload (64bits) receive during ENTDAA procedure.
436 * @param __PAYLOAD__ specifies the Device Characteristics capabilities retrieve during ENTDAA procedure.
437 * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFFFFFFFF.
438 * @retval The value of BCR Return value between Min_Data=0x00 and Max_Data=0xFF.
439 */
440 #define I3C_GET_DCR(__PAYLOAD__) (((uint32_t)((uint64_t)(__PAYLOAD__) >> I3C_DCR_IN_PAYLOAD_SHIFT)) & \
441 I3C_DCR_DCR)
442
443 /** @brief Get Advanced Capabilities.
444 * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure.
445 * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF.
446 * @retval The value of advanced capabilities:
447 * ENABLE: supports optional advanced capabilities.
448 * DISABLE: not supports optional advanced capabilities.
449 */
450 #define I3C_GET_ADVANCED_CAPABLE(__BCR__) (((((__BCR__) & I3C_BCR_BCR5_Msk) >> \
451 I3C_BCR_BCR5_Pos) == 1U) ? ENABLE : DISABLE)
452
453 /** @brief Get virtual target support.
454 * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure.
455 * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF.
456 * @retval The value of offline capable:
457 * ENABLE: is a Virtual Target
458 * DISABLE: is not a Virtual Target
459 */
460 #define I3C_GET_VIRTUAL_TGT(__BCR__) (((((__BCR__) & I3C_BCR_BCR4_Msk) >> \
461 I3C_BCR_BCR4_Pos) == 1U) ? ENABLE : DISABLE)
462
463 /** @brief Get offline capable.
464 * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure.
465 * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF.
466 * @retval The value of offline capable
467 * ENABLE: Device will not always respond to I3C Bus commands
468 * DISABLE: Device will always respond to I3C Bus commands
469 */
470 #define I3C_GET_OFFLINE_CAPABLE(__BCR__) (((((__BCR__) & I3C_BCR_BCR3_Msk) >> \
471 I3C_BCR_BCR3_Pos) == 1U) ? ENABLE : DISABLE)
472
473 /** @brief Get Max data speed limitation.
474 * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure.
475 * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF.
476 * @retval The value of offline capable:
477 * ENABLE: Limitation
478 * DISABLE: No Limitation
479 */
480 #define I3C_GET_MAX_DATA_SPEED_LIMIT(__BCR__) (((((__BCR__) & I3C_BCR_BCR0_Msk) >> \
481 I3C_BCR_BCR0_Pos) == 1U) ? ENABLE : DISABLE)
482
483 /** @brief Change uint32_t variable form big endian to little endian.
484 * @param __DATA__ .uint32_t variable in big endian.
485 * This parameter must be a number between Min_Data=0x00(uint32_t) and Max_Data=0xFFFFFFFF.
486 * @retval uint32_t variable in little endian.
487 */
488 #define I3C_BIG_TO_LITTLE_ENDIAN(__DATA__) ((uint32_t)((((__DATA__) & 0xff000000U) >> 24) | \
489 (((__DATA__) & 0x00ff0000U) >> 8) | \
490 (((__DATA__) & 0x0000ff00U) << 8) | \
491 (((__DATA__) & 0x000000ffU) << 24)))
492
493 /* Private variables -------------------------------------------------------------------------------------------------*/
494 /** @addtogroup I3C_Private_Variables
495 * @{
496 */
497 /* Structure containing address device and message type used for the private function I3C_Ctrl_IsDevice_Ready() */
498 typedef struct
499 {
500 uint8_t Address; /* Dynamic or Static target Address */
501 uint32_t MessageType; /* Message Type */
502
503 } I3C_DeviceTypeDef;
504 /**
505 * @}
506 */
507
508 /* Private function prototypes ---------------------------------------------------------------------------------------*/
509 /** @addtogroup I3C_Private_Functions
510 * @{
511 */
512 static HAL_StatusTypeDef I3C_Tgt_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
513 static HAL_StatusTypeDef I3C_Ctrl_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
514 static HAL_StatusTypeDef I3C_Tgt_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
515 static HAL_StatusTypeDef I3C_Tgt_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
516 #if defined(HAL_DMA_MODULE_ENABLED)
517 static HAL_StatusTypeDef I3C_Tgt_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
518 static HAL_StatusTypeDef I3C_Tgt_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
519 #endif /* HAL_DMA_MODULE_ENABLED */
520 static HAL_StatusTypeDef I3C_Tgt_HotJoin_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
521 static HAL_StatusTypeDef I3C_Tgt_CtrlRole_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
522 static HAL_StatusTypeDef I3C_Tgt_IBI_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
523 static HAL_StatusTypeDef I3C_Ctrl_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
524 static HAL_StatusTypeDef I3C_Ctrl_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
525 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
526 static HAL_StatusTypeDef I3C_Ctrl_Tx_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
527 static HAL_StatusTypeDef I3C_Ctrl_Rx_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
528 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
529 #if defined(HAL_DMA_MODULE_ENABLED)
530 static HAL_StatusTypeDef I3C_Ctrl_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
531 static HAL_StatusTypeDef I3C_Ctrl_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
532 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
533 #endif /* HAL_DMA_MODULE_ENABLED */
534 static HAL_StatusTypeDef I3C_Ctrl_DAA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
535 static HAL_StatusTypeDef I3C_Abort_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks);
536
537 static HAL_StatusTypeDef I3C_WaitOnDAAUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t timeout, uint32_t tickstart);
538 static HAL_StatusTypeDef I3C_WaitOnFlagUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t flag, FlagStatus flagstatus,
539 uint32_t timeout, uint32_t tickstart);
540 static void I3C_TransmitByteTreatment(I3C_HandleTypeDef *hi3c);
541 static void I3C_TransmitWordTreatment(I3C_HandleTypeDef *hi3c);
542 static void I3C_ReceiveByteTreatment(I3C_HandleTypeDef *hi3c);
543 static void I3C_ReceiveWordTreatment(I3C_HandleTypeDef *hi3c);
544 static void I3C_ControlDataTreatment(I3C_HandleTypeDef *hi3c);
545 static void I3C_ErrorTreatment(I3C_HandleTypeDef *hi3c);
546 static void I3C_GetErrorSources(I3C_HandleTypeDef *hi3c);
547 static void I3C_StateUpdate(I3C_HandleTypeDef *hi3c);
548 #if defined(HAL_DMA_MODULE_ENABLED)
549 static void I3C_DMAAbort(DMA_HandleTypeDef *hdma);
550 static void I3C_DMAControlTransmitCplt(DMA_HandleTypeDef *hdma);
551 static void I3C_DMADataTransmitCplt(DMA_HandleTypeDef *hdma);
552 static void I3C_DMADataReceiveCplt(DMA_HandleTypeDef *hdma);
553 static void I3C_DMAError(DMA_HandleTypeDef *hdma);
554 #endif /* HAL_DMA_MODULE_ENABLED */
555 static void I3C_Enable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest);
556 static void I3C_Disable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest);
557 static HAL_StatusTypeDef I3C_Xfer_PriorPreparation(I3C_HandleTypeDef *hi3c, uint8_t counter, uint32_t option);
558 static uint32_t I3C_FillTxBuffer_CCC(I3C_HandleTypeDef *hi3c,
559 uint32_t indexDesc,
560 uint32_t txSize,
561 uint32_t txCurrentIndex);
562 static uint32_t I3C_FillTxBuffer_Private(I3C_HandleTypeDef *hi3c,
563 uint32_t indexDesc,
564 uint32_t txSize,
565 uint32_t txCurrentIndex);
566 static HAL_StatusTypeDef I3C_ControlBuffer_PriorPreparation(I3C_HandleTypeDef *hi3c,
567 uint8_t counter,
568 uint32_t option);
569 static HAL_StatusTypeDef I3C_Ctrl_IsDevice_Ready(I3C_HandleTypeDef *hi3c,
570 const I3C_DeviceTypeDef *pDevice,
571 uint32_t trials,
572 uint32_t timeout);
573 static void I3C_TreatErrorCallback(I3C_HandleTypeDef *hi3c);
574 /**
575 * @}
576 */
577
578 /* Exported functions ------------------------------------------------------------------------------------------------*/
579 /** @addtogroup I3C_Exported_Functions I3C Exported Functions
580 * @{
581 */
582
583 /** @defgroup I3C_Exported_Functions_Group1 Initialization and de-initialization functions.
584 * @brief I3C initialization and de-initialization functions
585 *
586 @verbatim
587 =======================================================================================================================
588 ##### Initialization and de-initialization functions #####
589 =======================================================================================================================
590 [..] This subsection provides a set of functions allowing to initialize and deinitialize the I3Cx peripheral:
591
592 (+) Users must implement HAL_I3C_MspInit() function in which they configure all related peripherals
593 resources (APB and Kernel CLOCK, GPIO, DMA, IT and NVIC).
594
595 (+) Call the function HAL_I3C_Init() to configure the bus characteristic depends on the device mode
596 with the selected configuration below:
597
598 (++) Controller mode, Serial source clock wave form configuration:
599 (+++) SCL push pull low duration
600 (+++) SCL I3C high duration
601 (+++) SCL open drain low duration
602 (+++) SCL I2C high duration
603
604 (++) Controller mode, Bus timing configuration:
605 (+++) SDA hold time
606 (+++) Wait time
607 (+++) Bus free duration
608 (+++) Bus available duration
609
610 (++) Target mode, Bus timing configuration:
611 (+++) Bus available duration
612
613 (+) Call the function HAL_I3C_DeInit() to restore the default configuration of the selected I3Cx peripheral.
614
615 @endverbatim
616 * @{
617 */
618
619 /**
620 * @brief Initializes the I3C instance by activating the low-level hardware and configuring the bus
621 * characteristic according to the specified parameters in the I3C_InitTypeDef.
622 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
623 * for the specified I3C.
624 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
625 */
HAL_I3C_Init(I3C_HandleTypeDef * hi3c)626 HAL_StatusTypeDef HAL_I3C_Init(I3C_HandleTypeDef *hi3c)
627 {
628 HAL_StatusTypeDef status = HAL_OK;
629 uint32_t waveform_value;
630 uint32_t timing_value;
631
632 /* Check the I3C handle allocation */
633 if (hi3c == NULL)
634 {
635 status = HAL_ERROR;
636 }
637 else
638 {
639 /* Check the instance and the mode parameters */
640 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
641 assert_param(IS_I3C_MODE(hi3c->Mode));
642
643 /* Check the I3C state */
644 if (hi3c->State == HAL_I3C_STATE_RESET)
645 {
646 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
647 /* Init the I3C Callback settings */
648 /* Legacy weak CtrlTxCpltCallback */
649 hi3c->CtrlTxCpltCallback = HAL_I3C_CtrlTxCpltCallback;
650 /* Legacy weak CtrlRxCpltCallback */
651 hi3c->CtrlRxCpltCallback = HAL_I3C_CtrlRxCpltCallback;
652 /* Legacy weak CtrlMultipleXferCpltCallback */
653 hi3c->CtrlMultipleXferCpltCallback = HAL_I3C_CtrlMultipleXferCpltCallback;
654 /* Legacy weak CtrlDAACpltCallback */
655 hi3c->CtrlDAACpltCallback = HAL_I3C_CtrlDAACpltCallback;
656 /* Legacy weak TgtReqDynamicAddrCallback */
657 hi3c->TgtReqDynamicAddrCallback = HAL_I3C_TgtReqDynamicAddrCallback;
658 /* Legacy weak TgtTxCpltCallback */
659 hi3c->TgtTxCpltCallback = HAL_I3C_TgtTxCpltCallback;
660 /* Legacy weak TgtRxCpltCallback */
661 hi3c->TgtRxCpltCallback = HAL_I3C_TgtRxCpltCallback;
662 /* Legacy weak TgtHotJoinCallback */
663 hi3c->TgtHotJoinCallback = HAL_I3C_TgtHotJoinCallback;
664 /* Legacy weak NotifyCallback */
665 hi3c->NotifyCallback = HAL_I3C_NotifyCallback;
666 /* Legacy weak ErrorCallback */
667 hi3c->ErrorCallback = HAL_I3C_ErrorCallback;
668 /* Legacy weak AbortCpltCallback */
669 hi3c->AbortCpltCallback = HAL_I3C_AbortCpltCallback;
670
671 /* Check on the MSP init callback */
672 if (hi3c->MspInitCallback == NULL)
673 {
674 /* Legacy weak MspInit */
675 hi3c->MspInitCallback = HAL_I3C_MspInit;
676 }
677
678 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
679 hi3c->MspInitCallback(hi3c);
680 #else
681 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
682 HAL_I3C_MspInit(hi3c);
683
684 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
685 }
686
687 /* Update the I3C state to busy */
688 hi3c->State = HAL_I3C_STATE_BUSY;
689
690 /* Disable the selected I3C peripheral */
691 LL_I3C_Disable(hi3c->Instance);
692
693 /* Check on the I3C mode: initialization depends on the mode */
694 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
695 {
696 /* Check the parameters */
697 assert_param(IS_I3C_SDAHOLDTIME_VALUE(hi3c->Init.CtrlBusCharacteristic.SDAHoldTime));
698 assert_param(IS_I3C_WAITTIME_VALUE(hi3c->Init.CtrlBusCharacteristic.WaitTime));
699
700 /* Set Controller mode */
701 LL_I3C_SetMode(hi3c->Instance, LL_I3C_MODE_CONTROLLER);
702
703 /*----------------- SCL signal waveform configuration : I3C timing register 0 (I3C_TIMINGR0) ------------------ */
704 /* Set the controller SCL waveform */
705 waveform_value = ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLPPLowDuration |
706 ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLI3CHighDuration << I3C_TIMINGR0_SCLH_I3C_Pos) |
707 ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLODLowDuration << I3C_TIMINGR0_SCLL_OD_Pos) |
708 ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLI2CHighDuration << I3C_TIMINGR0_SCLH_I2C_Pos));
709
710 LL_I3C_ConfigClockWaveForm(hi3c->Instance, waveform_value);
711
712 /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------ */
713 /* Set SDA hold time, activity state, bus free duration and bus available duration */
714 timing_value = ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SDAHoldTime |
715 (uint32_t)hi3c->Init.CtrlBusCharacteristic.WaitTime |
716 ((uint32_t)hi3c->Init.CtrlBusCharacteristic.BusFreeDuration << I3C_TIMINGR1_FREE_Pos) |
717 (uint32_t)hi3c->Init.CtrlBusCharacteristic.BusIdleDuration);
718
719 LL_I3C_SetCtrlBusCharacteristic(hi3c->Instance, timing_value);
720 }
721 else
722 {
723 /* Set target mode */
724 LL_I3C_SetMode(hi3c->Instance, LL_I3C_MODE_TARGET);
725
726 /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------ */
727 /* Set the number of kernel clocks cycles for the bus available condition time */
728 LL_I3C_SetAvalTiming(hi3c->Instance, hi3c->Init.TgtBusCharacteristic.BusAvailableDuration);
729 }
730
731 /* Enable the selected I3C peripheral */
732 LL_I3C_Enable(hi3c->Instance);
733
734 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
735
736 /* Update I3C state */
737 hi3c->State = HAL_I3C_STATE_READY;
738 hi3c->PreviousState = HAL_I3C_STATE_READY;
739 }
740
741 return status;
742 }
743
744 /**
745 * @brief DeInitialize the I3C peripheral.
746 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
747 * for the specified I3C.
748 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
749 */
HAL_I3C_DeInit(I3C_HandleTypeDef * hi3c)750 HAL_StatusTypeDef HAL_I3C_DeInit(I3C_HandleTypeDef *hi3c)
751 {
752 HAL_StatusTypeDef status = HAL_OK;
753
754 /* Check the I3C handle allocation */
755 if (hi3c == NULL)
756 {
757 status = HAL_ERROR;
758 }
759 else
760 {
761 /* Check the parameters */
762 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
763
764 /* Update the I3C state to busy */
765 hi3c->State = HAL_I3C_STATE_BUSY;
766
767 /* Disable the selected I3C peripheral */
768 LL_I3C_Disable(hi3c->Instance);
769
770 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
771 /* Check on the MSP init callback */
772 if (hi3c->MspDeInitCallback == NULL)
773 {
774 /* Legacy weak MspDeInit */
775 hi3c->MspDeInitCallback = HAL_I3C_MspDeInit;
776 }
777
778 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
779 hi3c->MspDeInitCallback(hi3c);
780 #else
781 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
782 HAL_I3C_MspDeInit(hi3c);
783
784 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
785
786 /* Update the I3C Error code, state and mode */
787 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
788 hi3c->State = HAL_I3C_STATE_RESET;
789 hi3c->PreviousState = HAL_I3C_STATE_RESET;
790 hi3c->Mode = HAL_I3C_MODE_NONE;
791 }
792
793 return status;
794 }
795
796 /**
797 * @brief Initialize the I3C MSP.
798 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
799 * for the specified I3C.
800 * @retval None
801 */
HAL_I3C_MspInit(I3C_HandleTypeDef * hi3c)802 __weak void HAL_I3C_MspInit(I3C_HandleTypeDef *hi3c)
803 {
804 /* Prevent unused argument(s) compilation warning */
805 UNUSED(hi3c);
806
807 /* NOTE : This function should not be modified, when the callback is needed,
808 the HAL_I3C_MspInit could be implemented in the user file */
809 }
810
811 /**
812 * @brief DeInitialize the I3C MSP.
813 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
814 * for the specified I3C.
815 * @retval None
816 */
HAL_I3C_MspDeInit(I3C_HandleTypeDef * hi3c)817 __weak void HAL_I3C_MspDeInit(I3C_HandleTypeDef *hi3c)
818 {
819 /* Prevent unused argument(s) compilation warning */
820 UNUSED(hi3c);
821
822 /* NOTE : This function should not be modified, when the callback is needed,
823 the HAL_I3C_MspDeInit could be implemented in the user file */
824 }
825 /**
826 * @}
827 */
828
829 /** @defgroup I3C_Exported_Functions_Group2 Interrupt and callback functions.
830 * @brief I3C interrupt and callback functions.
831 *
832 @verbatim
833 =======================================================================================================================
834 ##### Interrupt and callback functions #####
835 =======================================================================================================================
836 [..] This subsection provides a set of functions allowing to manage callbacks and interrupts request:
837
838 (+) Register/Unregister callback function:
839 (++) Call the function HAL_I3C_RegisterCallback() to register an I3C user callback.
840 (++) Call the function HAL_I3C_RegisterNotifyCallback() to register an I3C user notification callback.
841 (++) Call the function HAL_I3C_RegisterDynamicAddrCallback() to register an I3C user address callback.
842 (++) Call the function HAL_I3C_RegisterHotJoinCallback() to register an I3C user hot join callback.
843 (++) Call the function HAL_I3C_UnRegisterCallback() to unregister an I3C user callback.
844
845 (+) Notification management function:
846 (++) Call the function HAL_I3C_ActivateNotification() to activate the I3C notifications.
847 (++) Call the function HAL_I3C_DeactivateNotification() to deactivate the I3C notifications.
848
849 (+) Controller callback functions:
850 (++) Users must implement HAL_I3C_CtrlTxCpltCallback() function when the transmission of private data or
851 Tx CCC transfer is completed.
852 (++) Users must implement HAL_I3C_CtrlRxCpltCallback() function when the reception of private data or
853 Rx CCC transfer is completed.
854 (++) Users must implement HAL_I3C_CtrlMultipleXferCpltCallback() function when the multiple
855 transfer of CCC, I3C private or I2C transfer is completed.
856 (++) Users must implement HAL_I3C_CtrlDAACpltCallback() function when Dynamic Address Assignment
857 procedure is completed.
858 (++) Users must implement HAL_I3C_TgtReqDynamicAddrCallback() function in the controller application
859 when a target sent its payload to the controller during Dynamic Address Assignment procedure.
860
861 (+) Target callback functions:
862 (++) Users must implement HAL_I3C_TgtTxCpltCallback() function when the transmission of private
863 data is completed.
864 (++) Users must implement HAL_I3C_TgtRxCpltCallback() function when the reception of private
865 data is completed.
866 (++) Users must implement HAL_I3C_TgtHotJoinCallback() function when a target hot join process
867 is completed.
868
869 (+) Common callback functions:
870 (++) Users must implement HAL_I3C_NotifyCallback() function when the device receives
871 an asynchronous event like IBI, a Hot-join, CCC command for target...
872 (++) Users must implement HAL_I3C_AbortCpltCallback() function when an abort process is completed.
873 (++) Users must implement HAL_I3C_ErrorCallback() function when an error is occurred.
874
875 (+) Interrupt and event function:
876 (++) Call the function HAL_I3C_ER_IRQHandler() in the ISR file to handle I3C error interrupts request.
877 (++) Call the function HAL_I3C_EV_IRQHandler() in the ISR file to handle I3C event interrupts request.
878 @endverbatim
879 * @{
880 */
881
882 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
883 /**
884 * @brief Register a User I3C Callback to be used instead of the weak predefined callback.
885 * @note The HAL_I3C_RegisterCallback() may be called before HAL_I3C_Init() in HAL_I3C_STATE_RESET
886 * to register callbacks for HAL_I3C_MSPINIT_CB_ID and HAL_I3C_MSPDEINIT_CB_ID
887 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
888 * for the specified I3C.
889 * @param callbackID : [IN] ID of the callback to be registered.
890 * This parameter can be one of the following values:
891 * @arg @ref HAL_I3C_CTRL_TX_COMPLETE_CB_ID
892 * @arg @ref HAL_I3C_CTRL_RX_COMPLETE_CB_ID
893 * @arg @ref HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID
894 * @arg @ref HAL_I3C_CTRL_DAA_COMPLETE_CB_ID
895 * @arg @ref HAL_I3C_TGT_TX_COMPLETE_CB_ID
896 * @arg @ref HAL_I3C_TGT_RX_COMPLETE_CB_ID
897 * @arg @ref HAL_I3C_ERROR_CB_ID
898 * @arg @ref HAL_I3C_ABORT_CB_ID
899 * @arg @ref HAL_I3C_MSPINIT_CB_ID
900 * @arg @ref HAL_I3C_MSPDEINIT_CB_ID
901 * @param pCallback : [IN] Pointer to the Callback function.
902 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
903 */
HAL_I3C_RegisterCallback(I3C_HandleTypeDef * hi3c,HAL_I3C_CallbackIDTypeDef callbackID,pI3C_CallbackTypeDef pCallback)904 HAL_StatusTypeDef HAL_I3C_RegisterCallback(I3C_HandleTypeDef *hi3c,
905 HAL_I3C_CallbackIDTypeDef callbackID,
906 pI3C_CallbackTypeDef pCallback)
907 {
908 HAL_StatusTypeDef status = HAL_OK;
909
910 /* Check the I3C handle allocation */
911 if (hi3c == NULL)
912 {
913 status = HAL_ERROR;
914 }
915 else
916 {
917 /* Check the user callback allocation */
918 if (pCallback == NULL)
919 {
920 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
921 status = HAL_ERROR;
922 }
923 else if (HAL_I3C_STATE_READY == hi3c->State)
924 {
925 switch (callbackID)
926 {
927 case HAL_I3C_CTRL_TX_COMPLETE_CB_ID :
928 hi3c->CtrlTxCpltCallback = pCallback;
929 break;
930
931 case HAL_I3C_CTRL_RX_COMPLETE_CB_ID :
932 hi3c->CtrlRxCpltCallback = pCallback;
933 break;
934
935 case HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID :
936 hi3c->CtrlMultipleXferCpltCallback = pCallback;
937 break;
938
939 case HAL_I3C_CTRL_DAA_COMPLETE_CB_ID :
940 hi3c->CtrlDAACpltCallback = pCallback;
941 break;
942
943 case HAL_I3C_TGT_TX_COMPLETE_CB_ID :
944 hi3c->TgtTxCpltCallback = pCallback;
945 break;
946
947 case HAL_I3C_TGT_RX_COMPLETE_CB_ID :
948 hi3c->TgtRxCpltCallback = pCallback;
949 break;
950
951 case HAL_I3C_ERROR_CB_ID :
952 hi3c->ErrorCallback = pCallback;
953 break;
954
955 case HAL_I3C_ABORT_CB_ID :
956 hi3c->AbortCpltCallback = pCallback;
957 break;
958
959 case HAL_I3C_MSPINIT_CB_ID :
960 hi3c->MspInitCallback = pCallback;
961 break;
962
963 case HAL_I3C_MSPDEINIT_CB_ID :
964 hi3c->MspDeInitCallback = pCallback;
965 break;
966
967 default :
968 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK;
969 status = HAL_ERROR;
970 break;
971 }
972 }
973 else if (HAL_I3C_STATE_RESET == hi3c->State)
974 {
975 switch (callbackID)
976 {
977 case HAL_I3C_MSPINIT_CB_ID :
978 hi3c->MspInitCallback = pCallback;
979 break;
980
981 case HAL_I3C_MSPDEINIT_CB_ID :
982 hi3c->MspDeInitCallback = pCallback;
983 break;
984
985 default :
986 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK;
987 status = HAL_ERROR;
988 break;
989 }
990 }
991 else
992 {
993 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
994 status = HAL_ERROR;
995 }
996 }
997
998 return status;
999 }
1000
1001 /**
1002 * @brief Register a User I3C Notify Callback to be used instead of the weak predefined callback.
1003 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
1004 * information for the specified I3C.
1005 * @param pNotifyCallback : [IN] Pointer to the Callback function.
1006 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1007 */
HAL_I3C_RegisterNotifyCallback(I3C_HandleTypeDef * hi3c,pI3C_NotifyCallbackTypeDef pNotifyCallback)1008 HAL_StatusTypeDef HAL_I3C_RegisterNotifyCallback(I3C_HandleTypeDef *hi3c, pI3C_NotifyCallbackTypeDef pNotifyCallback)
1009 {
1010 HAL_StatusTypeDef status = HAL_OK;
1011
1012 /* Check the I3C handle allocation */
1013 if (hi3c == NULL)
1014 {
1015 status = HAL_ERROR;
1016 }
1017 else
1018 {
1019 /* Check the user callback allocation */
1020 if (pNotifyCallback == NULL)
1021 {
1022 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1023 status = HAL_ERROR;
1024 }
1025 else if (HAL_I3C_STATE_READY == hi3c->State)
1026 {
1027 hi3c->NotifyCallback = pNotifyCallback;
1028 }
1029 else
1030 {
1031 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1032 status = HAL_ERROR;
1033 }
1034 }
1035
1036 return status;
1037 }
1038
1039 /**
1040 * @brief Register a User I3C dynamic address Callback to be used instead of the weak predefined callback.
1041 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
1042 * information for the specified I3C.
1043 * @param pTgtReqAddrCallback : [IN] Pointer to the Callback function.
1044 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1045 */
HAL_I3C_RegisterTgtReqDynamicAddrCallback(I3C_HandleTypeDef * hi3c,pI3C_TgtReqDynamicAddrCallbackTypeDef pTgtReqAddrCallback)1046 HAL_StatusTypeDef HAL_I3C_RegisterTgtReqDynamicAddrCallback(I3C_HandleTypeDef *hi3c,
1047 pI3C_TgtReqDynamicAddrCallbackTypeDef pTgtReqAddrCallback)
1048 {
1049 HAL_StatusTypeDef status = HAL_OK;
1050
1051 /* Check the I3C handle allocation */
1052 if (hi3c == NULL)
1053 {
1054 status = HAL_ERROR;
1055 }
1056 else
1057 {
1058 /* Check the user callback allocation */
1059 if (pTgtReqAddrCallback == NULL)
1060 {
1061 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1062 status = HAL_ERROR;
1063 }
1064 else if (HAL_I3C_STATE_READY == hi3c->State)
1065 {
1066 hi3c->TgtReqDynamicAddrCallback = pTgtReqAddrCallback;
1067 }
1068 else
1069 {
1070 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1071 status = HAL_ERROR;
1072 }
1073 }
1074
1075 return status;
1076 }
1077
1078 /**
1079 * @brief Register a User I3C hot join Callback to be used instead of the weak predefined callback.
1080 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
1081 * information for the specified I3C.
1082 * @param pTgtHotJoinCallback : [IN] Pointer to the Callback function.
1083 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1084 */
HAL_I3C_RegisterTgtHotJoinCallback(I3C_HandleTypeDef * hi3c,pI3C_TgtHotJoinCallbackTypeDef pTgtHotJoinCallback)1085 HAL_StatusTypeDef HAL_I3C_RegisterTgtHotJoinCallback(I3C_HandleTypeDef *hi3c,
1086 pI3C_TgtHotJoinCallbackTypeDef pTgtHotJoinCallback)
1087 {
1088 HAL_StatusTypeDef status = HAL_OK;
1089
1090 /* Check the I3C handle allocation */
1091 if (hi3c == NULL)
1092 {
1093 status = HAL_ERROR;
1094 }
1095 else
1096 {
1097 /* Check the user callback allocation */
1098 if (pTgtHotJoinCallback == NULL)
1099 {
1100 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1101 status = HAL_ERROR;
1102 }
1103 else if (HAL_I3C_STATE_READY == hi3c->State)
1104 {
1105 hi3c->TgtHotJoinCallback = pTgtHotJoinCallback;
1106 }
1107 else
1108 {
1109 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1110 status = HAL_ERROR;
1111 }
1112 }
1113
1114 return status;
1115 }
1116
1117 /**
1118 * @brief Unregister a user I3C Callback.
1119 * The I3C callback is redirected to the weak predefined callback
1120 * @note The HAL_I3C_UnRegisterCallback() may be called before HAL_I3C_Init() in HAL_I3C_STATE_RESET
1121 * to un-register callbacks for HAL_I3C_MSPINIT_CB_ID and HAL_I3C_MSPDEINIT_CB_ID
1122 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1123 * for the specified I3C.
1124 * @param callbackID : [IN] ID of the callback to be unregistered.
1125 * This parameter can be one of the following values:
1126 * @arg @ref HAL_I3C_CTRL_TX_COMPLETE_CB_ID
1127 * @arg @ref HAL_I3C_CTRL_RX_COMPLETE_CB_ID
1128 * @arg @ref HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID
1129 * @arg @ref HAL_I3C_CTRL_DAA_COMPLETE_CB_ID
1130 * @arg @ref HAL_I3C_TGT_REQ_DYNAMIC_ADDR_CB_ID
1131 * @arg @ref HAL_I3C_TGT_TX_COMPLETE_CB_ID
1132 * @arg @ref HAL_I3C_TGT_RX_COMPLETE_CB_ID
1133 * @arg @ref HAL_I3C_TGT_HOTJOIN_CB_ID
1134 * @arg @ref HAL_I3C_NOTIFY_CB_ID
1135 * @arg @ref HAL_I3C_ERROR_CB_ID
1136 * @arg @ref HAL_I3C_ABORT_CB_ID
1137 * @arg @ref HAL_I3C_MSPINIT_CB_ID
1138 * @arg @ref HAL_I3C_MSPDEINIT_CB_ID
1139 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1140 */
HAL_I3C_UnRegisterCallback(I3C_HandleTypeDef * hi3c,HAL_I3C_CallbackIDTypeDef callbackID)1141 HAL_StatusTypeDef HAL_I3C_UnRegisterCallback(I3C_HandleTypeDef *hi3c, HAL_I3C_CallbackIDTypeDef callbackID)
1142 {
1143 HAL_StatusTypeDef status = HAL_OK;
1144
1145 /* Check the I3C handle allocation */
1146 if (hi3c == NULL)
1147 {
1148 status = HAL_ERROR;
1149 }
1150 else
1151 {
1152 if (HAL_I3C_STATE_READY == hi3c->State)
1153 {
1154 switch (callbackID)
1155 {
1156 case HAL_I3C_CTRL_TX_COMPLETE_CB_ID :
1157 /* Legacy weak CtrlTxCpltCallback */
1158 hi3c->CtrlTxCpltCallback = HAL_I3C_CtrlTxCpltCallback;
1159 break;
1160
1161 case HAL_I3C_CTRL_RX_COMPLETE_CB_ID :
1162 /* Legacy weak CtrlRxCpltCallback */
1163 hi3c->CtrlRxCpltCallback = HAL_I3C_CtrlRxCpltCallback;
1164 break;
1165
1166 case HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID :
1167 /* Legacy weak CtrlMultipleXferCpltCallback */
1168 hi3c->CtrlMultipleXferCpltCallback = HAL_I3C_CtrlMultipleXferCpltCallback;
1169 break;
1170
1171 case HAL_I3C_CTRL_DAA_COMPLETE_CB_ID :
1172 /* Legacy weak CtrlDAACpltCallback */
1173 hi3c->CtrlDAACpltCallback = HAL_I3C_CtrlDAACpltCallback;
1174 break;
1175
1176 case HAL_I3C_TGT_REQ_DYNAMIC_ADDR_CB_ID :
1177 /*Legacy weak TgtReqDynamicAddrCallback */
1178 hi3c->TgtReqDynamicAddrCallback = HAL_I3C_TgtReqDynamicAddrCallback;
1179 break;
1180
1181 case HAL_I3C_TGT_TX_COMPLETE_CB_ID :
1182 /* Legacy weak TgtTxCpltCallback */
1183 hi3c->TgtTxCpltCallback = HAL_I3C_TgtTxCpltCallback;
1184 break;
1185
1186 case HAL_I3C_TGT_RX_COMPLETE_CB_ID :
1187 /* Legacy weak TgtRxCpltCallback */
1188 hi3c->TgtRxCpltCallback = HAL_I3C_TgtRxCpltCallback;
1189 break;
1190
1191 case HAL_I3C_TGT_HOTJOIN_CB_ID :
1192 /* Legacy weak TgtHotJoinCallback */
1193 hi3c->TgtHotJoinCallback = HAL_I3C_TgtHotJoinCallback;
1194 break;
1195
1196 case HAL_I3C_NOTIFY_CB_ID :
1197 /* Legacy weak NotifyCallback */
1198 hi3c->NotifyCallback = HAL_I3C_NotifyCallback;
1199 break;
1200
1201 case HAL_I3C_ERROR_CB_ID :
1202 /* Legacy weak ErrorCallback */
1203 hi3c->ErrorCallback = HAL_I3C_ErrorCallback;
1204 break;
1205
1206 case HAL_I3C_ABORT_CB_ID :
1207 /* Legacy weak AbortCpltCallback */
1208 hi3c->AbortCpltCallback = HAL_I3C_AbortCpltCallback;
1209 break;
1210
1211 case HAL_I3C_MSPINIT_CB_ID :
1212 /* Legacy weak MspInit */
1213 hi3c->MspInitCallback = HAL_I3C_MspInit;
1214 break;
1215
1216 case HAL_I3C_MSPDEINIT_CB_ID :
1217 /* Legacy weak MspDeInit */
1218 hi3c->MspDeInitCallback = HAL_I3C_MspDeInit;
1219 break;
1220
1221 default :
1222 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK;
1223 status = HAL_ERROR;
1224 break;
1225 }
1226 }
1227 else if (HAL_I3C_STATE_RESET == hi3c->State)
1228 {
1229 switch (callbackID)
1230 {
1231 case HAL_I3C_MSPINIT_CB_ID :
1232 /* Legacy weak MspInit */
1233 hi3c->MspInitCallback = HAL_I3C_MspInit;
1234 break;
1235
1236 case HAL_I3C_MSPDEINIT_CB_ID :
1237 /* Legacy weak MspDeInit */
1238 hi3c->MspDeInitCallback = HAL_I3C_MspDeInit;
1239 break;
1240
1241 default :
1242 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK;
1243 status = HAL_ERROR;
1244 break;
1245 }
1246 }
1247 else
1248 {
1249 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1250 status = HAL_ERROR;
1251 }
1252 }
1253
1254 return status;
1255 }
1256 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
1257
1258 /**
1259 * @brief This function permits to activate the I3C notifications.
1260 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
1261 * information for the specified I3C.
1262 * @param pXferData : [IN/OUT] Pointer to an I3C_XferTypeDef structure that contains the reception buffer to
1263 * retrieve data during broadcast CCC DEFTGTS and DEFGRPA when Target mode only.
1264 * @param interruptMask : [IN] Parameter indicates which interrupts will be enabled.
1265 * This parameter can be any combination of @arg I3C_TARGET_INTERRUPT when
1266 * the I3C is in target mode or a combination of @arg I3C_CONTROLLER_INTERRUPT
1267 * when it is in controller mode.
1268 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1269 */
HAL_I3C_ActivateNotification(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t interruptMask)1270 HAL_StatusTypeDef HAL_I3C_ActivateNotification(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData,
1271 uint32_t interruptMask)
1272 {
1273 HAL_StatusTypeDef status = HAL_OK;
1274
1275 /* Check on the handle */
1276 if (hi3c == NULL)
1277 {
1278 status = HAL_ERROR;
1279 }
1280 else
1281 {
1282 /* Check the instance and the mode parameters */
1283 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
1284 assert_param(IS_I3C_MODE(hi3c->Mode));
1285 assert_param(IS_I3C_INTERRUPTMASK(hi3c->Mode, interruptMask));
1286
1287 /* Check the I3C state and mode */
1288 if ((hi3c->State == HAL_I3C_STATE_RESET) ||
1289 ((hi3c->Mode != HAL_I3C_MODE_CONTROLLER) && (hi3c->Mode != HAL_I3C_MODE_TARGET)))
1290 {
1291 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1292 status = HAL_ERROR;
1293 }
1294 /* Check the I3C mode */
1295 else if ((hi3c->Mode == HAL_I3C_MODE_TARGET) &&
1296 ((interruptMask & (HAL_I3C_IT_DEFIE | HAL_I3C_IT_GRPIE)) != 0U) &&
1297 (pXferData == NULL))
1298 {
1299 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1300 status = HAL_ERROR;
1301 }
1302 else
1303 {
1304 /* Check the I3C mode */
1305 if (hi3c->Mode == HAL_I3C_MODE_TARGET)
1306 {
1307 if ((interruptMask & (HAL_I3C_IT_DEFIE | HAL_I3C_IT_GRPIE)) != 0U)
1308 {
1309 hi3c->pXferData = pXferData;
1310 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
1311
1312 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
1313 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
1314 {
1315 /* Set byte treatment function pointer */
1316 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
1317 }
1318 else
1319 {
1320 /* Set word treatment function pointer */
1321 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
1322 }
1323 }
1324 /* Store the target event treatment function */
1325 hi3c->XferISR = I3C_Tgt_Event_ISR;
1326 }
1327 else
1328 {
1329 /* Store the controller event treatment function */
1330 hi3c->XferISR = I3C_Ctrl_Event_ISR;
1331 }
1332
1333 /* Update handle parameters */
1334 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
1335 hi3c->State = HAL_I3C_STATE_LISTEN;
1336 hi3c->PreviousState = HAL_I3C_STATE_LISTEN;
1337
1338 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
1339 of I3C interrupt handle execution before current process unlock */
1340 /* Enable selected notifications */
1341 I3C_Enable_IRQ(hi3c, (interruptMask | I3C_XFER_LISTEN_IT));
1342 }
1343 }
1344
1345 return status;
1346 }
1347
1348 /**
1349 * @brief This function permits to deactivate the I3C notifications.
1350 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
1351 * information for the specified I3C.
1352 * @param interruptMask : [IN] Parameter indicates which interrupts will be disabled.
1353 * This parameter can be any combination of @arg I3C_TARGET_INTERRUPT when
1354 * the I3C is in target mode or a combination of @arg I3C_CONTROLLER_INTERRUPT
1355 * when it is in controller mode.
1356 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1357 */
HAL_I3C_DeactivateNotification(I3C_HandleTypeDef * hi3c,uint32_t interruptMask)1358 HAL_StatusTypeDef HAL_I3C_DeactivateNotification(I3C_HandleTypeDef *hi3c, uint32_t interruptMask)
1359 {
1360 HAL_StatusTypeDef status = HAL_OK;
1361
1362 /* Check on the handle */
1363 if (hi3c == NULL)
1364 {
1365 status = HAL_ERROR;
1366 }
1367 else
1368 {
1369 /* Check the instance parameter */
1370 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
1371
1372 /* Check on the State */
1373 if (hi3c->State == HAL_I3C_STATE_RESET)
1374 {
1375 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1376 status = HAL_ERROR;
1377 }
1378 else
1379 {
1380 /* Disable selected notifications */
1381 I3C_Disable_IRQ(hi3c, (interruptMask | I3C_XFER_LISTEN_IT));
1382
1383 if (READ_REG(hi3c->Instance->IER) == 0U)
1384 {
1385 /* Update the XferISR pointer */
1386 hi3c->XferISR = NULL;
1387
1388 /* Update I3C state */
1389 hi3c->State = HAL_I3C_STATE_READY;
1390 hi3c->PreviousState = HAL_I3C_STATE_READY;
1391 }
1392 }
1393 }
1394
1395 return status;
1396 }
1397
1398 /**
1399 * @brief Controller Transmission Complete callback.
1400 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1401 * for the specified I3C.
1402 * @retval None
1403 */
HAL_I3C_CtrlTxCpltCallback(I3C_HandleTypeDef * hi3c)1404 __weak void HAL_I3C_CtrlTxCpltCallback(I3C_HandleTypeDef *hi3c)
1405 {
1406 /* Prevent unused argument(s) compilation warning */
1407 UNUSED(hi3c);
1408
1409 /* NOTE : This function Should not be modified, when the callback is needed,
1410 the HAL_I3C_CtrlTxCpltCallback could be implemented in the user file
1411 */
1412 }
1413
1414 /**
1415 * @brief Controller Reception Complete callback.
1416 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1417 * for the specified I3C.
1418 * @retval None
1419 */
HAL_I3C_CtrlRxCpltCallback(I3C_HandleTypeDef * hi3c)1420 __weak void HAL_I3C_CtrlRxCpltCallback(I3C_HandleTypeDef *hi3c)
1421 {
1422 /* Prevent unused argument(s) compilation warning */
1423 UNUSED(hi3c);
1424
1425 /* NOTE : This function Should not be modified, when the callback is needed,
1426 the HAL_I3C_CtrlRxCpltCallback could be implemented in the user file
1427 */
1428 }
1429
1430 /**
1431 * @brief Controller multiple Direct CCC Command, I3C private or I2C transfer Complete callback.
1432 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1433 * for the specified I3C.
1434 * @retval None
1435 */
HAL_I3C_CtrlMultipleXferCpltCallback(I3C_HandleTypeDef * hi3c)1436 __weak void HAL_I3C_CtrlMultipleXferCpltCallback(I3C_HandleTypeDef *hi3c)
1437 {
1438 /* Prevent unused argument(s) compilation warning */
1439 UNUSED(hi3c);
1440
1441 /* NOTE : This function Should not be modified, when the callback is needed,
1442 the HAL_I3C_CtrlMultipleXferCpltCallback could be implemented in the user file
1443 */
1444 }
1445
1446 /**
1447 * @brief Controller dynamic address assignment Complete callback.
1448 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1449 * for the specified I3C.
1450 * @retval None
1451 */
HAL_I3C_CtrlDAACpltCallback(I3C_HandleTypeDef * hi3c)1452 __weak void HAL_I3C_CtrlDAACpltCallback(I3C_HandleTypeDef *hi3c)
1453 {
1454 /* Prevent unused argument(s) compilation warning */
1455 UNUSED(hi3c);
1456
1457 /* NOTE : This function Should not be modified, when the callback is needed,
1458 the HAL_I3C_CtrlDAACpltCallback could be implemented in the user file
1459 */
1460 }
1461
1462 /**
1463 * @brief Target Request Dynamic Address callback.
1464 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1465 * for the specified I3C.
1466 * @param targetPayload : [IN] Parameter indicates the target payload.
1467 * @retval None
1468 */
HAL_I3C_TgtReqDynamicAddrCallback(I3C_HandleTypeDef * hi3c,uint64_t targetPayload)1469 __weak void HAL_I3C_TgtReqDynamicAddrCallback(I3C_HandleTypeDef *hi3c, uint64_t targetPayload)
1470 {
1471 /* Prevent unused argument(s) compilation warning */
1472 UNUSED(hi3c);
1473 UNUSED(targetPayload);
1474
1475 /* NOTE : This function Should not be modified, when the callback is needed,
1476 the HAL_I3C_TgtReqDynamicAddrCallback could be implemented in the user file
1477 */
1478 }
1479
1480 /**
1481 * @brief Target Transmission Complete callback.
1482 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1483 * for the specified I3C.
1484 * @retval None
1485 */
HAL_I3C_TgtTxCpltCallback(I3C_HandleTypeDef * hi3c)1486 __weak void HAL_I3C_TgtTxCpltCallback(I3C_HandleTypeDef *hi3c)
1487 {
1488 /* Prevent unused argument(s) compilation warning */
1489 UNUSED(hi3c);
1490
1491 /* NOTE : This function Should not be modified, when the callback is needed,
1492 the HAL_I3C_TgtTxCpltCallback could be implemented in the user file
1493 */
1494 }
1495
1496 /**
1497 * @brief Target Reception Complete callback.
1498 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1499 * for the specified I3C.
1500 * @retval None
1501 */
HAL_I3C_TgtRxCpltCallback(I3C_HandleTypeDef * hi3c)1502 __weak void HAL_I3C_TgtRxCpltCallback(I3C_HandleTypeDef *hi3c)
1503 {
1504 /* Prevent unused argument(s) compilation warning */
1505 UNUSED(hi3c);
1506
1507 /* NOTE : This function Should not be modified, when the callback is needed,
1508 the HAL_I3C_TgtRxCpltCallback could be implemented in the user file
1509 */
1510 }
1511
1512 /**
1513 * @brief Target Hot join process Complete callback.
1514 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
1515 * information for the specified I3C.
1516 * @param dynamicAddress : [IN] The returned dynamic address value after the hot join process.
1517 * @retval None
1518 */
HAL_I3C_TgtHotJoinCallback(I3C_HandleTypeDef * hi3c,uint8_t dynamicAddress)1519 __weak void HAL_I3C_TgtHotJoinCallback(I3C_HandleTypeDef *hi3c, uint8_t dynamicAddress)
1520 {
1521 /* Prevent unused argument(s) compilation warning */
1522 UNUSED(hi3c);
1523 UNUSED(dynamicAddress);
1524
1525 /* NOTE : This function Should not be modified, when the callback is needed,
1526 the HAL_I3C_TgtHotJoinCallback could be implemented in the user file
1527 */
1528 }
1529
1530 /**
1531 * @brief Target/Controller Notification event callback.
1532 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1533 * for the specified I3C.
1534 * @param eventId : [IN] Parameter indicates which notification is signaled.
1535 * It can be a combination value of @ref HAL_I3C_Notification_ID_definition.
1536 * @retval None
1537 */
HAL_I3C_NotifyCallback(I3C_HandleTypeDef * hi3c,uint32_t eventId)1538 __weak void HAL_I3C_NotifyCallback(I3C_HandleTypeDef *hi3c, uint32_t eventId)
1539 {
1540 /* Prevent unused argument(s) compilation warning */
1541 UNUSED(hi3c);
1542 UNUSED(eventId);
1543
1544 /* NOTE : This function Should not be modified, when the callback is needed,
1545 the HAL_I3C_NotifyCallback could be implemented in the user file
1546 */
1547 }
1548
1549 /**
1550 * @brief Abort complete callback.
1551 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1552 * for the specified I3C.
1553 * @retval None
1554 */
HAL_I3C_AbortCpltCallback(I3C_HandleTypeDef * hi3c)1555 __weak void HAL_I3C_AbortCpltCallback(I3C_HandleTypeDef *hi3c)
1556 {
1557 /* Prevent unused argument(s) compilation warning */
1558 UNUSED(hi3c);
1559
1560 /* NOTE : This function Should not be modified, when the callback is needed,
1561 the HAL_I3C_AbortCpltCallback could be implemented in the user file
1562 */
1563 }
1564
1565 /**
1566 * @brief Error callback.
1567 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1568 * for the specified I3C.
1569 * @retval None
1570 */
HAL_I3C_ErrorCallback(I3C_HandleTypeDef * hi3c)1571 __weak void HAL_I3C_ErrorCallback(I3C_HandleTypeDef *hi3c)
1572 {
1573 /* Prevent unused argument(s) compilation warning */
1574 UNUSED(hi3c);
1575
1576 /* NOTE : This function Should not be modified, when the callback is needed,
1577 the HAL_I3C_ErrorCallback could be implemented in the user file
1578 */
1579 }
1580
1581 /**
1582 * @brief This function handles I3C error interrupt request.
1583 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1584 * for the specified I3C.
1585 * @retval None
1586 */
HAL_I3C_ER_IRQHandler(I3C_HandleTypeDef * hi3c)1587 void HAL_I3C_ER_IRQHandler(I3C_HandleTypeDef *hi3c)
1588 {
1589 uint32_t it_flag = READ_REG(hi3c->Instance->EVR);
1590 uint32_t it_source = READ_REG(hi3c->Instance->IER);
1591
1592 /* Check on the error interrupt flag and source */
1593 if ((I3C_CHECK_FLAG(it_flag, HAL_I3C_FLAG_ERRF) != RESET) &&
1594 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_ERRIE) != RESET))
1595 {
1596 /* Clear the error flag */
1597 LL_I3C_ClearFlag_ERR(hi3c->Instance);
1598
1599 if (hi3c->State != HAL_I3C_STATE_ABORT)
1600 {
1601 /* Get error sources */
1602 I3C_GetErrorSources(hi3c);
1603 }
1604
1605 /* Errors treatment */
1606 I3C_ErrorTreatment(hi3c);
1607 }
1608 }
1609
1610 /**
1611 * @brief This function handles I3C event interrupt request.
1612 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1613 * for the specified I3C.
1614 * @retval None
1615 */
HAL_I3C_EV_IRQHandler(I3C_HandleTypeDef * hi3c)1616 void HAL_I3C_EV_IRQHandler(I3C_HandleTypeDef *hi3c) /* Derogation MISRAC2012-Rule-8.13 */
1617 {
1618 uint32_t it_flags = READ_REG(hi3c->Instance->EVR);
1619 uint32_t it_sources = READ_REG(hi3c->Instance->IER);
1620
1621 uint32_t it_masks = (uint32_t)(it_flags & it_sources);
1622
1623 /* I3C events treatment */
1624 if (hi3c->XferISR != NULL)
1625 {
1626 hi3c->XferISR(hi3c, it_masks);
1627 }
1628 }
1629 /**
1630 * @}
1631 */
1632
1633 /** @defgroup I3C_Exported_Functions_Group3 Configuration functions.
1634 * @brief I3C configuration functions.
1635 *
1636 @verbatim
1637 =======================================================================================================================
1638 ##### Configuration functions #####
1639 =======================================================================================================================
1640 [..] This subsection provides a set of functions allowing to configure the I3C instances.
1641
1642 (+) Call the function HAL_I3C_Ctrl_BusCharacteristicConfig() to modify the controller Bus Characteristics
1643 after initialize the bus through HAL_I3C_Init.
1644
1645 (+) Call the function HAL_I3C_Tgt_BusCharacteristicConfig() to modify the target Bus Characteristics
1646 after initialize the bus through HAL_I3C_Init.
1647
1648 (+) Call the function HAL_I3C_SetConfigFifo() to set FIFOs configuration (enabled FIFOs and
1649 threshold level) with the selected parameters in the configuration structure I3C_FifoConfTypeDef.
1650
1651 (+) Call the function HAL_I3C_Ctrl_Config() to configure the I3C Controller instances with the selected
1652 parameters in the configuration structure I3C_CtrlConfTypeDef.
1653 This function is called only when mode is Controller.
1654
1655 (+) Call the function HAL_I3C_Tgt_Config() to configure the I3C Target instances with the selected
1656 parameters in the configuration structure I3C_TgtConfTypeDef.
1657 This function is called only when mode is Target.
1658
1659 (+) Call the function HAL_I3C_Ctrl_ConfigBusDevices() to configure Hardware device characteristics register
1660 with Devices capabilities present on the Bus.
1661 All different characteristics must be fill through structure I3C_DeviceConfTypeDef.
1662 This function is called only when mode is Controller.
1663
1664 (+) Call the function HAL_I3C_AddDescToFrame() to prepare the full transfer usecase in a Controller transfer
1665 descriptor which contained different buffer pointers and their associated size through I3C_XferTypeDef.
1666 This function must be called before initiate any communication transfer.
1667 (+) Call the function HAL_I3C_Ctrl_SetConfigResetPattern() to configure the insertion of the reset pattern
1668 at the end of a Frame.
1669 (+) Call the function HAL_I3C_Ctrl_GetConfigResetPattern() to get the current reset pattern configuration
1670
1671 [..]
1672 (@) Users must call all above functions after I3C initialization.
1673
1674 @endverbatim
1675 * @{
1676 */
1677
1678 /**
1679 * @brief Configure the Controller Bus characterics.
1680 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1681 * for the specified I3C.
1682 * @param pConfig : [IN] Pointer to an LL_I3C_CtrlBusConfTypeDef structure contains controller bus configuration.
1683 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1684 */
HAL_I3C_Ctrl_BusCharacteristicConfig(I3C_HandleTypeDef * hi3c,const LL_I3C_CtrlBusConfTypeDef * pConfig)1685 HAL_StatusTypeDef HAL_I3C_Ctrl_BusCharacteristicConfig(I3C_HandleTypeDef *hi3c,
1686 const LL_I3C_CtrlBusConfTypeDef *pConfig)
1687 {
1688 HAL_StatusTypeDef status = HAL_OK;
1689 uint32_t waveform_value;
1690 uint32_t timing_value;
1691
1692 /* Check the I3C handle allocation */
1693 if (hi3c == NULL)
1694 {
1695 status = HAL_ERROR;
1696 }
1697 else
1698 {
1699 /* Check the instance and the mode parameters */
1700 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
1701 assert_param(IS_I3C_MODE(hi3c->Mode));
1702
1703 /* Check on user parameters */
1704 if (pConfig == NULL)
1705 {
1706 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1707 status = HAL_ERROR;
1708 }
1709 /* Check the I3C state and mode */
1710 else if ((hi3c->State != HAL_I3C_STATE_READY) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER))
1711 {
1712 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1713 status = HAL_ERROR;
1714 }
1715 else
1716 {
1717 /* Check the parameters */
1718 assert_param(IS_I3C_SDAHOLDTIME_VALUE(pConfig->SDAHoldTime));
1719 assert_param(IS_I3C_WAITTIME_VALUE(pConfig->WaitTime));
1720
1721 /* Disable the selected I3C peripheral */
1722 LL_I3C_Disable(hi3c->Instance);
1723
1724 /*----------------- SCL signal waveform configuration : I3C timing register 0 (I3C_TIMINGR0) ------------------ */
1725 /* Set the controller SCL waveform */
1726 waveform_value = ((uint32_t)pConfig->SCLPPLowDuration |
1727 ((uint32_t)pConfig->SCLI3CHighDuration << I3C_TIMINGR0_SCLH_I3C_Pos) |
1728 ((uint32_t)pConfig->SCLODLowDuration << I3C_TIMINGR0_SCLL_OD_Pos) |
1729 ((uint32_t)pConfig->SCLI2CHighDuration << I3C_TIMINGR0_SCLH_I2C_Pos));
1730
1731 LL_I3C_ConfigClockWaveForm(hi3c->Instance, waveform_value);
1732
1733 /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------ */
1734 /* Set SDA hold time, activity state, bus free duration and bus available duration */
1735 timing_value = ((uint32_t)pConfig->SDAHoldTime |
1736 (uint32_t)pConfig->WaitTime |
1737 ((uint32_t)pConfig->BusFreeDuration << I3C_TIMINGR1_FREE_Pos) |
1738 (uint32_t)pConfig->BusIdleDuration);
1739
1740 LL_I3C_SetCtrlBusCharacteristic(hi3c->Instance, timing_value);
1741
1742 /* Enable the selected I3C peripheral */
1743 LL_I3C_Enable(hi3c->Instance);
1744 }
1745 }
1746
1747 return status;
1748 }
1749
1750 /**
1751 * @brief Configure the target Bus characterics.
1752 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1753 * for the specified I3C.
1754 * @param pConfig : [IN] Pointer to an LL_I3C_TgtBusConfTypeDef structure contains target bus configuration.
1755 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1756 */
HAL_I3C_Tgt_BusCharacteristicConfig(I3C_HandleTypeDef * hi3c,const LL_I3C_TgtBusConfTypeDef * pConfig)1757 HAL_StatusTypeDef HAL_I3C_Tgt_BusCharacteristicConfig(I3C_HandleTypeDef *hi3c,
1758 const LL_I3C_TgtBusConfTypeDef *pConfig)
1759 {
1760 HAL_StatusTypeDef status = HAL_OK;
1761
1762 /* Check the I3C handle allocation */
1763 if (hi3c == NULL)
1764 {
1765 status = HAL_ERROR;
1766 }
1767 else
1768 {
1769 /* Check on user parameters */
1770 if (pConfig == NULL)
1771 {
1772 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1773 status = HAL_ERROR;
1774 }
1775 else
1776 {
1777 /* Check the instance and the mode parameters */
1778 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
1779 assert_param(IS_I3C_MODE(hi3c->Mode));
1780
1781 /* Check the I3C state and mode */
1782 if ((hi3c->State != HAL_I3C_STATE_READY) || (hi3c->Mode != HAL_I3C_MODE_TARGET))
1783 {
1784 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1785 status = HAL_ERROR;
1786 }
1787 else
1788 {
1789 /* Disable the selected I3C peripheral */
1790 LL_I3C_Disable(hi3c->Instance);
1791
1792 /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ---------------------------- */
1793 /* Set the number of kernel clocks cycles for the bus available condition time */
1794 LL_I3C_SetAvalTiming(hi3c->Instance, pConfig->BusAvailableDuration);
1795
1796 /* Enable the selected I3C peripheral */
1797 LL_I3C_Enable(hi3c->Instance);
1798 }
1799 }
1800 }
1801
1802 return status;
1803 }
1804
1805 /**
1806 * @brief Set I3C FIFOs configuration.
1807 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1808 * for the specified I3C.
1809 * @param pConfig : [IN] Pointer to an I3C_FifoConfTypeDef structure contains FIFOs configuration.
1810 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1811 */
HAL_I3C_SetConfigFifo(I3C_HandleTypeDef * hi3c,const I3C_FifoConfTypeDef * pConfig)1812 HAL_StatusTypeDef HAL_I3C_SetConfigFifo(I3C_HandleTypeDef *hi3c, const I3C_FifoConfTypeDef *pConfig)
1813 {
1814 HAL_StatusTypeDef status = HAL_OK;
1815 uint32_t cfgr_value;
1816 uint32_t cfgr_mask;
1817
1818 /* Check the I3C handle */
1819 if (hi3c == NULL)
1820 {
1821 status = HAL_ERROR;
1822 }
1823 else
1824 {
1825 /* Check on user parameters */
1826 if (pConfig == NULL)
1827 {
1828 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1829 status = HAL_ERROR;
1830 }
1831 /* Check the I3C state */
1832 else if (hi3c->State == HAL_I3C_STATE_RESET)
1833 {
1834 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1835 status = HAL_ERROR;
1836 }
1837 else
1838 {
1839 /* Check the instance and the mode parameters */
1840 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
1841 assert_param(IS_I3C_MODE(hi3c->Mode));
1842
1843 /* Check configuration parameters */
1844 assert_param(IS_I3C_TXFIFOTHRESHOLD_VALUE(pConfig->TxFifoThreshold));
1845 assert_param(IS_I3C_RXFIFOTHRESHOLD_VALUE(pConfig->RxFifoThreshold));
1846
1847 /* Set Tx and Rx Fifo threshold */
1848 cfgr_value = (pConfig->TxFifoThreshold | pConfig->RxFifoThreshold);
1849 cfgr_mask = (I3C_CFGR_TXTHRES | I3C_CFGR_RXTHRES);
1850
1851 /* Check on the I3C mode: Control and status FIFOs available only with controller mode */
1852 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
1853 {
1854 /* Check configuration parameters */
1855 assert_param(IS_I3C_CONTROLFIFOSTATE_VALUE(pConfig->ControlFifo));
1856 assert_param(IS_I3C_STATUSFIFOSTATE_VALUE(pConfig->StatusFifo));
1857
1858 /* Set Control and Status Fifo states */
1859 cfgr_value |= (pConfig->StatusFifo | pConfig->ControlFifo);
1860 cfgr_mask |= (I3C_CFGR_TMODE | I3C_CFGR_SMODE);
1861 }
1862
1863 /* Set configuration in the CFGR register */
1864 MODIFY_REG(hi3c->Instance->CFGR, cfgr_mask, cfgr_value);
1865 }
1866 }
1867
1868 return status;
1869 }
1870
1871 /**
1872 * @brief Set I3C controller configuration.
1873 * @note This function is called only when the I3C instance is initialized as controller.
1874 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1875 * for the specified I3C.
1876 * @param pConfig : [IN] Pointer to an I3C_CtrlConfTypeDef structure that contains controller configuration.
1877 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1878 */
HAL_I3C_Ctrl_Config(I3C_HandleTypeDef * hi3c,const I3C_CtrlConfTypeDef * pConfig)1879 HAL_StatusTypeDef HAL_I3C_Ctrl_Config(I3C_HandleTypeDef *hi3c, const I3C_CtrlConfTypeDef *pConfig)
1880 {
1881 HAL_StatusTypeDef status = HAL_OK;
1882 uint32_t timing2_value;
1883 uint32_t cfgr_value;
1884
1885 /* Check the I3C handle */
1886 if (hi3c == NULL)
1887 {
1888 status = HAL_ERROR;
1889 }
1890 else
1891 {
1892 /* Check the instance and the mode parameters */
1893 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
1894 assert_param(IS_I3C_MODE(hi3c->Mode));
1895
1896 /* Check on user parameters */
1897 if (pConfig == NULL)
1898 {
1899 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1900 status = HAL_ERROR;
1901 }
1902 /* Check the I3C state and mode */
1903 else if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER))
1904 {
1905 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1906 status = HAL_ERROR;
1907 }
1908 else
1909 {
1910 /* Check configuration parameters values */
1911 assert_param(IS_I3C_DYNAMICADDRESS_VALUE(pConfig->DynamicAddr));
1912 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HighKeeperSDA));
1913 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HotJoinAllowed));
1914 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->ACKStallState));
1915 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->CCCStallState));
1916 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->TxStallState));
1917 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->RxStallState));
1918
1919 /* Disable the selected I3C peripheral */
1920 LL_I3C_Disable(hi3c->Instance);
1921
1922 /* Calculate value to be written in timing register 2 */
1923 timing2_value = (((uint32_t)pConfig->StallTime << I3C_TIMINGR2_STALL_Pos) |
1924 ((uint32_t)pConfig->ACKStallState << I3C_TIMINGR2_STALLA_Pos) |
1925 ((uint32_t)pConfig->CCCStallState << I3C_TIMINGR2_STALLC_Pos) |
1926 ((uint32_t)pConfig->TxStallState << I3C_TIMINGR2_STALLD_Pos) |
1927 ((uint32_t)pConfig->RxStallState << I3C_TIMINGR2_STALLT_Pos));
1928
1929 /* Set value in timing 2 register */
1930 WRITE_REG(hi3c->Instance->TIMINGR2, timing2_value);
1931
1932 /* Calculate value to be written in CFGR register */
1933 cfgr_value = (((uint32_t)pConfig->HighKeeperSDA << I3C_CFGR_HKSDAEN_Pos) |
1934 ((uint32_t)pConfig->HotJoinAllowed << I3C_CFGR_HJACK_Pos));
1935
1936 /* Set hot join acknowledge and high keeper values */
1937 MODIFY_REG(hi3c->Instance->CFGR, I3C_CFGR_HKSDAEN | I3C_CFGR_HJACK, cfgr_value);
1938
1939 /* Set dynamic address value */
1940 LL_I3C_SetOwnDynamicAddress(hi3c->Instance, pConfig->DynamicAddr);
1941
1942 /* Validate the controller dynamic address */
1943 LL_I3C_EnableOwnDynAddress(hi3c->Instance);
1944
1945 /* Enable the selected I3C peripheral */
1946 LL_I3C_Enable(hi3c->Instance);
1947 }
1948 }
1949
1950 return status;
1951 }
1952
1953 /**
1954 * @brief Set I3C target configuration.
1955 * @note This function is called only when the I3C instance is initialized as target.
1956 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
1957 * for the specified I3C.
1958 * @param pConfig : [IN] Pointer to an I3C_TgtConfTypeDef structure that contains target configuration.
1959 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
1960 */
HAL_I3C_Tgt_Config(I3C_HandleTypeDef * hi3c,const I3C_TgtConfTypeDef * pConfig)1961 HAL_StatusTypeDef HAL_I3C_Tgt_Config(I3C_HandleTypeDef *hi3c, const I3C_TgtConfTypeDef *pConfig)
1962 {
1963 HAL_StatusTypeDef status = HAL_OK;
1964 uint32_t getmxdsr_value;
1965 uint32_t maxrlr_value;
1966 uint32_t crccapr_value;
1967 uint32_t bcr_value;
1968 uint32_t devr0_value;
1969
1970 /* Check the I3C handle */
1971 if (hi3c == NULL)
1972 {
1973 status = HAL_ERROR;
1974 }
1975 else
1976 {
1977 /* Check the instance and the mode parameters */
1978 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
1979 assert_param(IS_I3C_MODE(hi3c->Mode));
1980
1981 /* Check on user parameters */
1982 if (pConfig == NULL)
1983 {
1984 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
1985 status = HAL_ERROR;
1986 }
1987 /* Check the I3C state and mode */
1988 else if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_TARGET))
1989 {
1990 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
1991 status = HAL_ERROR;
1992 }
1993 else
1994 {
1995 /* Check configuration parameters values */
1996 assert_param(IS_I3C_HANDOFFACTIVITYSTATE_VALUE(pConfig->HandOffActivityState));
1997 assert_param(IS_I3C_TSCOTIME_VALUE(pConfig->DataTurnAroundDuration));
1998 assert_param(IS_I3C_MAXSPEEDDATA_VALUE(pConfig->MaxDataSpeed));
1999 assert_param(IS_I3C_IBIPAYLOADSIZE_VALUE(pConfig->IBIPayloadSize));
2000 assert_param(IS_I3C_MIPIIDENTIFIER_VALUE(pConfig->MIPIIdentifier));
2001 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HandOffDelay));
2002 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->GroupAddrCapability));
2003 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->PendingReadMDB));
2004 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->IBIPayload));
2005 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->MaxSpeedLimitation));
2006 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->CtrlCapability));
2007 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->IBIRequest));
2008 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->CtrlRoleRequest));
2009 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HotJoinRequest));
2010
2011 /* Disable the selected I3C peripheral */
2012 LL_I3C_Disable(hi3c->Instance);
2013
2014 /* Calculate value to be written in the GETMXDSR register */
2015 getmxdsr_value = (pConfig->HandOffActivityState | pConfig->MaxDataSpeed | pConfig->DataTurnAroundDuration |
2016 ((uint32_t)pConfig->MaxReadTurnAround << I3C_GETMXDSR_RDTURN_Pos));
2017
2018 /* Set value in GETMXDSR register */
2019 WRITE_REG(hi3c->Instance->GETMXDSR, getmxdsr_value);
2020
2021 /* Calculate value to be written in MAXRLR register */
2022 maxrlr_value = (pConfig->IBIPayloadSize | (pConfig->MaxReadDataSize & I3C_MAXRLR_MRL));
2023
2024 /* Set payload size and max read data size in MAXRLR register */
2025 WRITE_REG(hi3c->Instance->MAXRLR, maxrlr_value);
2026
2027 /* Set max write data size in MAXWLR register */
2028 LL_I3C_SetMaxWriteLength(hi3c->Instance, pConfig->MaxWriteDataSize);
2029
2030 /* Set MIPI identifier value in EPIDR register */
2031 LL_I3C_SetMIPIInstanceID(hi3c->Instance, pConfig->MIPIIdentifier);
2032
2033 /* Set identifier value in DCR register */
2034 LL_I3C_SetDeviceCharacteristics(hi3c->Instance, pConfig->Identifier);
2035
2036 /* Calculate value to be written in CRCCAPR register */
2037 crccapr_value = (((uint32_t)pConfig->HandOffDelay << I3C_CRCAPR_CAPDHOFF_Pos) |
2038 ((uint32_t)pConfig->GroupAddrCapability << I3C_CRCAPR_CAPGRP_Pos));
2039
2040 /* Set hand off dealy and group address capability in CRCCAPR register */
2041 WRITE_REG(hi3c->Instance->CRCAPR, crccapr_value);
2042
2043 /* Set pending read MDB notification value in GETCAPR register */
2044 LL_I3C_SetPendingReadMDB(hi3c->Instance, ((uint32_t)pConfig->PendingReadMDB << I3C_GETCAPR_CAPPEND_Pos));
2045
2046 /* Calculate value to be written in BCR register */
2047 bcr_value = (((uint32_t)pConfig->MaxSpeedLimitation << I3C_BCR_BCR0_Pos) |
2048 ((uint32_t)pConfig->IBIPayload << I3C_BCR_BCR2_Pos) |
2049 ((uint32_t)pConfig->CtrlCapability << I3C_BCR_BCR6_Pos));
2050
2051 /* Set control capability, IBI payload support and max speed limitation in BCR register */
2052 WRITE_REG(hi3c->Instance->BCR, bcr_value);
2053
2054 /* Calculate value to be written in CFGR register */
2055 devr0_value = (((uint32_t)pConfig->IBIRequest << I3C_DEVR0_IBIEN_Pos) |
2056 ((uint32_t)pConfig->CtrlRoleRequest << I3C_DEVR0_CREN_Pos) |
2057 ((uint32_t)pConfig->HotJoinRequest << I3C_DEVR0_HJEN_Pos));
2058
2059 /* Set IBI request, control role request and hot join request in DEVR0 register */
2060 MODIFY_REG(hi3c->Instance->DEVR0, (I3C_DEVR0_HJEN | I3C_DEVR0_IBIEN | I3C_DEVR0_CREN), devr0_value);
2061
2062 /* Enable the selected I3C peripheral */
2063 LL_I3C_Enable(hi3c->Instance);
2064 }
2065 }
2066
2067 return status;
2068 }
2069
2070 /**
2071 * @brief Set I3C bus devices configuration.
2072 * @note This function is called only when the I3C instance is initialized as controller.
2073 * This function can be called by the controller application to help the automatic treatment when target have
2074 * capability of IBI and/or Control-Role.
2075 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2076 * for the specified I3C.
2077 * @param pDesc : [IN] Pointer to an I3C_DeviceConfTypeDef descriptor that contains the bus devices
2078 * configurations.
2079 * @param nbDevice : [IN] Value specifies the number of devices to be treated.
2080 * This parameter must be a number between Min_Data=1U and Max_Data=4U.
2081 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2082 */
HAL_I3C_Ctrl_ConfigBusDevices(I3C_HandleTypeDef * hi3c,const I3C_DeviceConfTypeDef * pDesc,uint8_t nbDevice)2083 HAL_StatusTypeDef HAL_I3C_Ctrl_ConfigBusDevices(I3C_HandleTypeDef *hi3c,
2084 const I3C_DeviceConfTypeDef *pDesc,
2085 uint8_t nbDevice)
2086 {
2087 HAL_StatusTypeDef status = HAL_OK;
2088 uint32_t write_value;
2089
2090 /* Check the I3C handle */
2091 if (hi3c == NULL)
2092 {
2093 status = HAL_ERROR;
2094 }
2095 else
2096 {
2097 /* Check on user parameters */
2098 if (pDesc == NULL)
2099 {
2100 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
2101 status = HAL_ERROR;
2102 }
2103 /* Check the I3C state and mode */
2104 else if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER))
2105 {
2106 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2107 status = HAL_ERROR;
2108 }
2109 else
2110 {
2111 /* Check the instance and the mode parameters */
2112 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2113 assert_param(IS_I3C_MODE(hi3c->Mode));
2114 assert_param(IS_I3C_DEVICE_VALUE(nbDevice));
2115
2116 /* Loop on the nbDevice to be treated */
2117 for (uint32_t index = 0U; index < nbDevice; index++)
2118 {
2119 /* Check configuration parameters values */
2120 assert_param(IS_I3C_DEVICE_VALUE(pDesc[index].DeviceIndex));
2121 assert_param(IS_I3C_DYNAMICADDRESS_VALUE(pDesc[index].TargetDynamicAddr));
2122 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].IBIAck));
2123 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].CtrlRoleReqAck));
2124 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].CtrlStopTransfer));
2125 assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].IBIPayload));
2126
2127 /* Set value to be written */
2128 write_value = (((uint32_t)pDesc[index].TargetDynamicAddr << I3C_DEVRX_DA_Pos) |
2129 ((uint32_t)pDesc[index].IBIAck << I3C_DEVRX_IBIACK_Pos) |
2130 ((uint32_t)pDesc[index].CtrlRoleReqAck << I3C_DEVRX_CRACK_Pos) |
2131 ((uint32_t)pDesc[index].CtrlStopTransfer << I3C_DEVRX_SUSP_Pos) |
2132 ((uint32_t)pDesc[index].IBIPayload << I3C_DEVRX_IBIDEN_Pos));
2133
2134 /* Write configuration in the DEVRx register */
2135 WRITE_REG(hi3c->Instance->DEVRX[(pDesc[index].DeviceIndex - 1U)], write_value);
2136 }
2137 }
2138 }
2139
2140 return status;
2141 }
2142
2143 /**
2144 * @brief Add Private or CCC descriptor in the user data transfer controller descriptor.
2145 * @note This function must be called before initiate initiate any controller communication transfer. This function
2146 * help the preparation of the full transfer usecase in a transfer descriptor which contained different buffer
2147 * pointers and their associated size through I3C_XferTypeDef.
2148 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
2149 * multiple transmission frames.
2150 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2151 * for the specified I3C.
2152 * @param pCCCDesc : [IN] Pointer to an I3C_CCCTypeDef structure that contains the CCC descriptor information.
2153 * @param pPrivateDesc : [IN] Pointer to an I3C_PrivateTypeDef structure that contains the transfer descriptor.
2154 * @param pXferData : [IN/OUT] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
2155 * (control buffer, data buffer and status buffer).
2156 * @param nbFrame : [IN] The number of CCC commands or the number of device to treat.
2157 * @param option : [IN] Value indicates the transfer option. It can be one value of @ref I3C_OPTION_DEFINITION
2158 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2159 */
HAL_I3C_AddDescToFrame(I3C_HandleTypeDef * hi3c,const I3C_CCCTypeDef * pCCCDesc,const I3C_PrivateTypeDef * pPrivateDesc,I3C_XferTypeDef * pXferData,uint8_t nbFrame,uint32_t option)2160 HAL_StatusTypeDef HAL_I3C_AddDescToFrame(I3C_HandleTypeDef *hi3c,
2161 const I3C_CCCTypeDef *pCCCDesc,
2162 const I3C_PrivateTypeDef *pPrivateDesc,
2163 I3C_XferTypeDef *pXferData,
2164 uint8_t nbFrame,
2165 uint32_t option)
2166 {
2167 HAL_I3C_StateTypeDef handle_state;
2168 HAL_StatusTypeDef status = HAL_OK;
2169
2170 /* check on the handle */
2171 if (hi3c == NULL)
2172 {
2173 status = HAL_ERROR;
2174 }
2175 else
2176 {
2177 /* Get I3C handle state */
2178 handle_state = hi3c->State;
2179
2180 /* Set handle transfer parameters */
2181 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
2182 hi3c->pCCCDesc = pCCCDesc;
2183 hi3c->pPrivateDesc = pPrivateDesc;
2184 hi3c->pXferData = pXferData;
2185 hi3c->RxXferCount = 0;
2186 hi3c->TxXferCount = 0;
2187
2188 /* Prepare Direction, and Check on user parameters */
2189 if (((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC) ||
2190 ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT))
2191 {
2192 /* Check on user parameters */
2193 if ((pCCCDesc == NULL) ||
2194 (pXferData == NULL) ||
2195 (nbFrame < 1U) ||
2196 (((option & (I3C_OPERATION_TYPE_MASK | I3C_DEFINE_BYTE_MASK)) == \
2197 (LL_I3C_CONTROLLER_MTYPE_DIRECT | I3C_DEFINE_BYTE_MASK)) && (pCCCDesc->CCCBuf.Size == 0U)))
2198 {
2199 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
2200 status = HAL_ERROR;
2201 }
2202 }
2203 else
2204 {
2205 /* Check on user parameters */
2206 if ((pPrivateDesc == NULL) || (pXferData == NULL) || (nbFrame <= 0U))
2207 {
2208 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
2209 status = HAL_ERROR;
2210 }
2211 }
2212
2213 if (status == HAL_OK)
2214 {
2215 /* check on the State */
2216 if ((handle_state == HAL_I3C_STATE_READY) || (handle_state == HAL_I3C_STATE_LISTEN))
2217 {
2218 /* I3C control buffer prior preparation */
2219 if (I3C_ControlBuffer_PriorPreparation(hi3c, nbFrame, option) != HAL_OK)
2220 {
2221 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
2222 status = HAL_ERROR;
2223 }
2224
2225 /* I3C Tx Buffer prior preparation, set and check RxCount */
2226 if (I3C_Xfer_PriorPreparation(hi3c, nbFrame, option) != HAL_OK)
2227 {
2228 status = HAL_ERROR;
2229 }
2230 }
2231 else
2232 {
2233 status = HAL_BUSY;
2234 }
2235 }
2236 }
2237
2238 return status;
2239 }
2240
2241 /**
2242 * @brief Set the configuration of the inserted reset pattern at the end of a Frame.
2243 * @note When the transfer descriptor contains multiple frames with RESTART option, the reset pattern at the end of
2244 * RSTACT CCC frame is not possible.
2245 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains
2246 * the configuration information for the specified I3C.
2247 * @param resetPattern : [IN] Specifies the reset pattern configuration.
2248 * It can be a value of @ref I3C_RESET_PATTERN
2249 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2250 */
HAL_I3C_Ctrl_SetConfigResetPattern(I3C_HandleTypeDef * hi3c,uint32_t resetPattern)2251 HAL_StatusTypeDef HAL_I3C_Ctrl_SetConfigResetPattern(I3C_HandleTypeDef *hi3c, uint32_t resetPattern)
2252 {
2253 HAL_StatusTypeDef status = HAL_OK;
2254 HAL_I3C_StateTypeDef handle_state;
2255
2256 /* check on the handle */
2257 if (hi3c == NULL)
2258 {
2259 status = HAL_ERROR;
2260 }
2261 else
2262 {
2263 /* Check the instance and the mode parameters */
2264 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2265 assert_param(IS_I3C_MODE(hi3c->Mode));
2266 assert_param(IS_I3C_RESET_PATTERN(resetPattern));
2267
2268 /* Get I3C handle state */
2269 handle_state = hi3c->State;
2270
2271 /* check on the Mode */
2272 if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
2273 {
2274 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2275 status = HAL_ERROR;
2276 }
2277 /* check on the State */
2278 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
2279 {
2280 status = HAL_BUSY;
2281 }
2282 else
2283 {
2284 hi3c->State = HAL_I3C_STATE_BUSY;
2285
2286 if (resetPattern == HAL_I3C_RESET_PATTERN_ENABLE)
2287 {
2288 LL_I3C_EnableResetPattern(hi3c->Instance);
2289 }
2290 else
2291 {
2292 LL_I3C_DisableResetPattern(hi3c->Instance);
2293 }
2294
2295 /* At the end of process update state to Previous state */
2296 I3C_StateUpdate(hi3c);
2297 }
2298 }
2299
2300 return status;
2301 }
2302
2303 /**
2304 * @brief Get the configuration of the inserted reset pattern at the end of a Frame.
2305 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains
2306 * the configuration information for the specified I3C.
2307 * @param pResetPattern : [OUT] Pointer to the current reset pattern configuration.
2308 * It can be a value of @ref I3C_RESET_PATTERN
2309 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2310 */
HAL_I3C_Ctrl_GetConfigResetPattern(I3C_HandleTypeDef * hi3c,uint32_t * pResetPattern)2311 HAL_StatusTypeDef HAL_I3C_Ctrl_GetConfigResetPattern(I3C_HandleTypeDef *hi3c, uint32_t *pResetPattern)
2312 {
2313 HAL_StatusTypeDef status = HAL_OK;
2314
2315 /* check on the handle */
2316 if (hi3c == NULL)
2317 {
2318 status = HAL_ERROR;
2319 }
2320 /* Check on user parameters */
2321 else if (pResetPattern == NULL)
2322 {
2323 status = HAL_ERROR;
2324 }
2325 else
2326 {
2327 /* Check the instance and the mode parameters */
2328 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2329 assert_param(IS_I3C_MODE(hi3c->Mode));
2330
2331 /* Check if the reset pattern configuration is enabled */
2332 if (LL_I3C_IsEnabledResetPattern(hi3c->Instance) == 1U)
2333 {
2334 *pResetPattern = HAL_I3C_RESET_PATTERN_ENABLE;
2335 }
2336 else
2337 {
2338 *pResetPattern = HAL_I3C_RESET_PATTERN_DISABLE;
2339 }
2340 }
2341
2342 return status;
2343 }
2344
2345 /**
2346 * @}
2347 */
2348
2349 /** @defgroup I3C_Exported_Functions_Group4 FIFO Management functions.
2350 * @brief I3C FIFO management functions.
2351 *
2352 @verbatim
2353 =======================================================================================================================
2354 ##### FIFO Management functions #####
2355 =======================================================================================================================
2356 [..] This subsection provides a set of functions allowing to manage I3C FIFOs.
2357
2358 (+) Call the function HAL_I3C_FlushAllFifo() to flush the content of all used FIFOs (Control, Status,
2359 Tx and Rx FIFO).
2360 (+) Call the function HAL_I3C_FlushTxFifo() to flush only the content of Tx FIFO.
2361 (+) Call the function HAL_I3C_FlushRxFifo() to flush only the content of Rx FIFO.
2362 (+) Call the function HAL_I3C_FlushControlFifo() to flush only the content of Control FIFO.
2363 This function is called only when mode is controller.
2364 (+) Call the function HAL_I3C_FlushStatusFifo() to flush only the content of Status FIFO.
2365 This function is called only when mode is controller.
2366 (+) Call the function HAL_I3C_ClearConfigFifo() to clear the FIFOs configuration and set it to default values.
2367 (+) Call the function HAL_I3C_GetConfigFifo() to get the current FIFOs configuration (enabled FIFOs and
2368 threshold level).
2369
2370 (+) Users must not call all above functions before I3C initialization.
2371
2372 (+) Users should call Flush APIs after an end of process, before starting a transfer or in case of bus
2373 failure and error detection.
2374
2375 @endverbatim
2376 * @{
2377 */
2378
2379 /**
2380 * @brief Flush all I3C FIFOs content.
2381 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2382 * for the specified I3C.
2383 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2384 */
HAL_I3C_FlushAllFifo(I3C_HandleTypeDef * hi3c)2385 HAL_StatusTypeDef HAL_I3C_FlushAllFifo(I3C_HandleTypeDef *hi3c)
2386 {
2387 HAL_StatusTypeDef status = HAL_OK;
2388 uint32_t cfgr_value;
2389
2390 /* Check the I3C handle allocation */
2391 if (hi3c == NULL)
2392 {
2393 status = HAL_ERROR;
2394 }
2395 else
2396 {
2397 /* Check the instance and the mode parameters */
2398 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2399 assert_param(IS_I3C_MODE(hi3c->Mode));
2400
2401 /* Check the I3C state */
2402 if (hi3c->State == HAL_I3C_STATE_RESET)
2403 {
2404 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2405 status = HAL_ERROR;
2406 }
2407 else
2408 {
2409 /* Flush the content of Tx and Rx Fifo */
2410 cfgr_value = (I3C_CFGR_TXFLUSH | I3C_CFGR_RXFLUSH);
2411
2412 /* Check on the I3C mode: Control and status FIFOs available only with controller mode */
2413 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
2414 {
2415 /* Flush the content of Control and Status Fifo */
2416 cfgr_value = (I3C_CFGR_SFLUSH | I3C_CFGR_CFLUSH);
2417 }
2418
2419 /* Set configuration in the CFGR register */
2420 MODIFY_REG(hi3c->Instance->CFGR, cfgr_value, cfgr_value);
2421 }
2422 }
2423
2424 return status;
2425 }
2426
2427 /**
2428 * @brief Flush I3C Tx FIFO content.
2429 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2430 * for the specified I3C.
2431 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2432 */
HAL_I3C_FlushTxFifo(I3C_HandleTypeDef * hi3c)2433 HAL_StatusTypeDef HAL_I3C_FlushTxFifo(I3C_HandleTypeDef *hi3c)
2434 {
2435 HAL_StatusTypeDef status = HAL_OK;
2436
2437 /* Check the I3C handle allocation */
2438 if (hi3c == NULL)
2439 {
2440 status = HAL_ERROR;
2441 }
2442 else
2443 {
2444 /* Check the instance and the mode parameters */
2445 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2446 assert_param(IS_I3C_MODE(hi3c->Mode));
2447
2448 /* Check the I3C state */
2449 if (hi3c->State == HAL_I3C_STATE_RESET)
2450 {
2451 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2452 status = HAL_ERROR;
2453 }
2454 else
2455 {
2456 /* Flush the content of Tx Fifo */
2457 LL_I3C_RequestTxFIFOFlush(hi3c->Instance);
2458 }
2459 }
2460
2461 return status;
2462 }
2463
2464 /**
2465 * @brief Flush I3C Rx FIFO content.
2466 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2467 * for the specified I3C.
2468 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2469 */
HAL_I3C_FlushRxFifo(I3C_HandleTypeDef * hi3c)2470 HAL_StatusTypeDef HAL_I3C_FlushRxFifo(I3C_HandleTypeDef *hi3c)
2471 {
2472 HAL_StatusTypeDef status = HAL_OK;
2473
2474 /* Check the I3C handle allocation */
2475 if (hi3c == NULL)
2476 {
2477 status = HAL_ERROR;
2478 }
2479 else
2480 {
2481
2482 /* Check the instance and the mode parameters */
2483 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2484 assert_param(IS_I3C_MODE(hi3c->Mode));
2485
2486 /* Check the I3C state */
2487 if (hi3c->State == HAL_I3C_STATE_RESET)
2488 {
2489 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2490 status = HAL_ERROR;
2491 }
2492 else
2493 {
2494 /* Flush the content of Rx Fifo */
2495 LL_I3C_RequestRxFIFOFlush(hi3c->Instance);
2496 }
2497 }
2498
2499 return status;
2500 }
2501
2502 /**
2503 * @brief Flush I3C control FIFO content.
2504 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2505 * for the specified I3C.
2506 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2507 */
HAL_I3C_FlushControlFifo(I3C_HandleTypeDef * hi3c)2508 HAL_StatusTypeDef HAL_I3C_FlushControlFifo(I3C_HandleTypeDef *hi3c)
2509 {
2510 HAL_StatusTypeDef status = HAL_OK;
2511
2512 /* Check the I3C handle allocation */
2513 if (hi3c == NULL)
2514 {
2515 status = HAL_ERROR;
2516 }
2517 else
2518 {
2519 /* Check the instance and the mode parameters */
2520 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2521 assert_param(IS_I3C_MODE(hi3c->Mode));
2522
2523 /* Check the I3C state and mode */
2524 if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER))
2525 {
2526 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2527 status = HAL_ERROR;
2528 }
2529 else
2530 {
2531 /* Flush the content of Control Fifo */
2532 LL_I3C_RequestControlFIFOFlush(hi3c->Instance);
2533 }
2534 }
2535
2536 return status;
2537 }
2538
2539 /**
2540 * @brief Flush I3C status FIFO content.
2541 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2542 * for the specified I3C.
2543 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2544 */
HAL_I3C_FlushStatusFifo(I3C_HandleTypeDef * hi3c)2545 HAL_StatusTypeDef HAL_I3C_FlushStatusFifo(I3C_HandleTypeDef *hi3c)
2546 {
2547 HAL_StatusTypeDef status = HAL_OK;
2548
2549 /* Check the I3C handle allocation */
2550 if (hi3c == NULL)
2551 {
2552 status = HAL_ERROR;
2553 }
2554 else
2555 {
2556 /* Check the instance and the mode parameters */
2557 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2558 assert_param(IS_I3C_MODE(hi3c->Mode));
2559
2560 /* Check the I3C state and mode */
2561 if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER))
2562 {
2563 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2564 status = HAL_ERROR;
2565 }
2566 else
2567 {
2568 /* Flush the content of Control Fifo */
2569 LL_I3C_RequestStatusFIFOFlush(hi3c->Instance);
2570 }
2571 }
2572
2573 return status;
2574 }
2575
2576 /**
2577 * @brief Clear I3C FIFOs configuration and set it to default values.
2578 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2579 * for the specified I3C.
2580 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2581 */
HAL_I3C_ClearConfigFifo(I3C_HandleTypeDef * hi3c)2582 HAL_StatusTypeDef HAL_I3C_ClearConfigFifo(I3C_HandleTypeDef *hi3c)
2583 {
2584 HAL_StatusTypeDef status = HAL_OK;
2585 uint32_t cfgr_value;
2586 uint32_t cfgr_mask;
2587
2588 /* Check the I3C handle allocation */
2589 if (hi3c == NULL)
2590 {
2591 status = HAL_ERROR;
2592 }
2593 else
2594 {
2595 /* Check the instance and the mode parameters */
2596 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2597 assert_param(IS_I3C_MODE(hi3c->Mode));
2598
2599 /* Check the I3C state */
2600 if (hi3c->State == HAL_I3C_STATE_RESET)
2601 {
2602 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2603 status = HAL_ERROR;
2604 }
2605 else
2606 {
2607 /* Clear Tx Fifo and Rx Fifo threshold and set it to default value */
2608 cfgr_value = (LL_I3C_TXFIFO_THRESHOLD_1_4 | LL_I3C_RXFIFO_THRESHOLD_1_4);
2609 cfgr_mask = (I3C_CFGR_TXTHRES | I3C_CFGR_RXTHRES);
2610
2611 /* Check on the I3C mode: Control and status FIFOs available only with controller mode */
2612 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
2613 {
2614 /* Disable the status and Control Fifo state */
2615 cfgr_value |= (HAL_I3C_STATUSFIFO_DISABLE | HAL_I3C_CONTROLFIFO_DISABLE);
2616 cfgr_mask |= (I3C_CFGR_TMODE | I3C_CFGR_SMODE);
2617 }
2618
2619 /* Set configuration in the CFGR register */
2620 MODIFY_REG(hi3c->Instance->CFGR, cfgr_mask, cfgr_value);
2621 }
2622 }
2623
2624 return status;
2625 }
2626
2627 /**
2628 * @brief Get I3C FIFOs current configuration.
2629 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2630 * for the specified I3C.
2631 * @param pConfig : [IN/OUT] Pointer to an I3C_FifoConfTypeDef structure that returns current FIFOs configuration.
2632 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2633 */
HAL_I3C_GetConfigFifo(I3C_HandleTypeDef * hi3c,I3C_FifoConfTypeDef * pConfig)2634 HAL_StatusTypeDef HAL_I3C_GetConfigFifo(I3C_HandleTypeDef *hi3c, I3C_FifoConfTypeDef *pConfig)
2635 {
2636 HAL_StatusTypeDef status = HAL_OK;
2637
2638 /* Check the I3C handle */
2639 if (hi3c == NULL)
2640 {
2641 status = HAL_ERROR;
2642 }
2643 else
2644 {
2645 /* Check the instance and the mode parameters */
2646 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2647 assert_param(IS_I3C_MODE(hi3c->Mode));
2648
2649 /* Check on user parameters */
2650 if (pConfig == NULL)
2651 {
2652 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
2653 status = HAL_ERROR;
2654 }
2655 /* Check the I3C state */
2656 else if (hi3c->State == HAL_I3C_STATE_RESET)
2657 {
2658 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2659 status = HAL_ERROR;
2660 }
2661 else
2662 {
2663 /* Get Tx Fifo threshold */
2664 pConfig->TxFifoThreshold = LL_I3C_GetTxFIFOThreshold(hi3c->Instance);
2665
2666 /* Get Rx Fifo threshold */
2667 pConfig->RxFifoThreshold = LL_I3C_GetRxFIFOThreshold(hi3c->Instance);
2668
2669 /* Get the Control Fifo state */
2670 pConfig->ControlFifo = (uint32_t)(LL_I3C_IsEnabledControlFIFO(hi3c->Instance) << I3C_CFGR_TMODE_Pos);
2671
2672 /* Get the status Fifo state */
2673 pConfig->StatusFifo = (uint32_t)(LL_I3C_IsEnabledStatusFIFO(hi3c->Instance) << I3C_CFGR_SMODE_Pos);
2674 }
2675 }
2676
2677 return status;
2678 }
2679 /**
2680 * @}
2681 */
2682
2683 /** @defgroup I3C_Exported_Functions_Group5 Controller operational functions.
2684 * @brief I3C controller operational functions.
2685 *
2686 @verbatim
2687 =======================================================================================================================
2688 ##### Controller operational functions #####
2689 =======================================================================================================================
2690 [..] This subsection provides a set of functions allowing to manage controller I3C operation.
2691
2692 (+) Call the function HAL_I3C_Ctrl_TransmitCCC() to transmit direct write or a broadcast
2693 CCC command in polling mode.
2694 (+) Call the function HAL_I3C_Ctrl_TransmitCCC_IT() to transmit direct write or a broadcast
2695 CCC command in interrupt mode.
2696 (+) Call the function HAL_I3C_Ctrl_TransmitCCC_DMA() to transmit direct write or a broadcast
2697 CCC command in DMA mode.
2698 (+) Call the function HAL_I3C_Ctrl_ReceiveCCC() to transmit direct read CCC command in polling mode.
2699 (+) Call the function HAL_I3C_Ctrl_ReceiveCCC_IT() to transmit direct read CCC command in interrupt mode.
2700 (+) Call the function HAL_I3C_Ctrl_ReceiveCCC_DMA() to transmit direct read CCC command in DMA mode.
2701 (+) Call the function HAL_I3C_Ctrl_Transmit() to transmit private data in polling mode.
2702 (+) Call the function HAL_I3C_Ctrl_Transmit_IT() to transmit private data in interrupt mode.
2703 (+) Call the function HAL_I3C_Ctrl_Transmit_DMA() to transmit private data in DMA mode.
2704 (+) Call the function HAL_I3C_Ctrl_Receive() to receive private data in polling mode.
2705 (+) Call the function HAL_I3C_Ctrl_Receive_IT() to receive private data in interrupt mode.
2706 (+) Call the function HAL_I3C_Ctrl_Receive_DMA() to receive private data in DMA mode.
2707 (+) Call the function HAL_I3C_Ctrl_MultipleTransfer_IT() to transfer I3C or I2C private data or CCC command
2708 in multiple direction in interrupt mode.
2709 (+) Call the function HAL_I3C_Ctrl_MultipleTransfer_DMA() to transfer I3C or I2C private data or CCC command
2710 in multiple direction in DMA mode.
2711 (+) Call the function HAL_I3C_Ctrl_DynAddrAssign() to send a broadcast ENTDAA CCC
2712 command in polling mode.
2713 (+) Call the function HAL_I3C_Ctrl_DynAddrAssign_IT() to send a broadcast ENTDAA CCC
2714 command in interrupt mode.
2715 (+) Call the function HAL_I3C_Ctrl_SetDynAddr() to set, asscociate the target dynamic address
2716 during the Dynamic Address Assignment processus.
2717 (+) Call the function HAL_I3C_Ctrl_IsDeviceI3C_Ready() to check if I3C target device is ready.
2718 (+) Call the function HAL_I3C_Ctrl_IsDeviceI2C_Ready() to check if I2C target device is ready.
2719 (+) Call the function HAL_I3C_Ctrl_GenerateArbitration to send arbitration
2720 (message header {S + 0x7E + W + STOP}) in polling mode
2721
2722 (+) Those functions are called only when mode is Controller.
2723
2724 @endverbatim
2725 * @{
2726 */
2727
2728 /**
2729 * @brief Controller transmit direct write or a broadcast CCC command in polling mode.
2730 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
2731 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
2732 * multiple transmission frames.
2733 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2734 * for the specified I3C.
2735 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
2736 * (control buffer, data buffer and status buffer).
2737 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
2738 * @param timeout : [IN] Timeout duration in millisecond.
2739 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2740 */
HAL_I3C_Ctrl_TransmitCCC(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)2741 HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC(I3C_HandleTypeDef *hi3c,
2742 I3C_XferTypeDef *pXferData,
2743 uint32_t timeout)
2744 {
2745 uint32_t tickstart;
2746 uint32_t exit_condition;
2747 HAL_StatusTypeDef status = HAL_OK;
2748 HAL_I3C_StateTypeDef handle_state;
2749
2750 /* check on the handle */
2751 if (hi3c == NULL)
2752 {
2753 status = HAL_ERROR;
2754 }
2755 else
2756 {
2757 /* Check the instance and the mode parameters */
2758 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2759 assert_param(IS_I3C_MODE(hi3c->Mode));
2760
2761 /* Get I3C handle state */
2762 handle_state = hi3c->State;
2763
2764 /* Check on user parameters */
2765 if ((pXferData == NULL) ||
2766 ((hi3c->TxXferCount != 0U) && (pXferData->TxBuf.pBuffer == NULL)))
2767 {
2768 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
2769 status = HAL_ERROR;
2770 }
2771 /* check on the Mode */
2772 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
2773 {
2774 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2775 status = HAL_ERROR;
2776 }
2777 /* check on the State */
2778 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
2779 {
2780 /* Update returned status value */
2781 status = HAL_BUSY;
2782 }
2783 else
2784 {
2785 /* Set handle transfer parameters */
2786 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
2787 hi3c->State = HAL_I3C_STATE_BUSY_TX;
2788 hi3c->pXferData = pXferData;
2789
2790 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
2791 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
2792 {
2793 /* Set byte treatment function pointer */
2794 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
2795 }
2796 else
2797 {
2798 /* Set word treatment function pointer */
2799 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
2800 }
2801
2802 /* Init tickstart for timeout management */
2803 tickstart = HAL_GetTick();
2804
2805 /* Check on control FIFO enable/disable state */
2806 if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U)
2807 {
2808 /* Initiate a Start condition */
2809 LL_I3C_RequestTransfer(hi3c->Instance);
2810 }
2811 else
2812 {
2813 /* Decrement remaining control buffer data counter */
2814 hi3c->ControlXferCount--;
2815
2816 /* Initiate a start condition by writing in the CR register */
2817 WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer);
2818
2819 /* Increment Buffer pointer */
2820 hi3c->pXferData->CtrlBuf.pBuffer++;
2821 }
2822
2823 /* Do while until FC (Frame Complete) is set or timeout */
2824 do
2825 {
2826 /* Check if hardware asks for control data */
2827 if (hi3c->ControlXferCount > 0U)
2828 {
2829 /* Call control data treatment function */
2830 I3C_ControlDataTreatment(hi3c);
2831 }
2832
2833 /* Check if hardware asks for Tx data */
2834 if (hi3c->TxXferCount > 0U)
2835 {
2836 /* Call transmit treatment function */
2837 hi3c->ptrTxFunc(hi3c);
2838 }
2839
2840 /* Check for the timeout */
2841 if (timeout != HAL_MAX_DELAY)
2842 {
2843 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
2844 {
2845 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
2846 status = HAL_TIMEOUT;
2847 break;
2848 }
2849 }
2850
2851 if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U))
2852 {
2853 /* Clear frame complete flag */
2854 LL_I3C_ClearFlag_FC(hi3c->Instance);
2855
2856 /* Then Initiate a Start condition */
2857 LL_I3C_RequestTransfer(hi3c->Instance);
2858 }
2859
2860 /* Calculate exit_condition value based on Frame complete and error flags */
2861 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
2862 } while ((exit_condition == 0U) ||
2863 ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U)));
2864
2865 /* Clear frame complete flag */
2866 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
2867 {
2868 LL_I3C_ClearFlag_FC(hi3c->Instance);
2869 }
2870
2871 /* Check on error flag */
2872 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
2873 {
2874 /* Clear error flag */
2875 LL_I3C_ClearFlag_ERR(hi3c->Instance);
2876
2877 /* Update handle error code parameter */
2878 I3C_GetErrorSources(hi3c);
2879
2880 /* Update returned status value */
2881 status = HAL_ERROR;
2882 }
2883
2884 /* At the end of Tx process update state to Previous state */
2885 I3C_StateUpdate(hi3c);
2886 }
2887 }
2888
2889 return status;
2890 }
2891
2892 /**
2893 * @brief Controller transmit direct write or a broadcast CCC command in interrupt mode.
2894 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
2895 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
2896 * multiple transmission frames.
2897 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2898 * for the specified I3C.
2899 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
2900 * (control buffer, data buffer and status buffer).
2901 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
2902 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2903 */
HAL_I3C_Ctrl_TransmitCCC_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)2904 HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC_IT(I3C_HandleTypeDef *hi3c,
2905 I3C_XferTypeDef *pXferData)
2906 {
2907 HAL_I3C_StateTypeDef handle_state;
2908 HAL_StatusTypeDef status = HAL_OK;
2909
2910 /* check on the handle */
2911 if (hi3c == NULL)
2912 {
2913 status = HAL_ERROR;
2914 }
2915 else
2916 {
2917 /* Check the instance and the mode parameters */
2918 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
2919 assert_param(IS_I3C_MODE(hi3c->Mode));
2920
2921 /* Get I3C handle state */
2922 handle_state = hi3c->State;
2923
2924 /* Check on user parameters */
2925 if ((pXferData == NULL) ||
2926 ((hi3c->TxXferCount != 0U) && (pXferData->TxBuf.pBuffer == NULL)))
2927 {
2928 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
2929 status = HAL_ERROR;
2930 }
2931 /* check on the Mode */
2932 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
2933 {
2934 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
2935 status = HAL_ERROR;
2936 }
2937 /* check on the State */
2938 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
2939 {
2940 status = HAL_BUSY;
2941 }
2942 else
2943 {
2944 /* Set handle transfer parameters */
2945 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
2946
2947 if (handle_state == HAL_I3C_STATE_LISTEN)
2948 {
2949 hi3c->XferISR = I3C_Ctrl_Tx_Listen_Event_ISR;
2950 }
2951 else
2952 {
2953 hi3c->XferISR = I3C_Ctrl_Tx_ISR;
2954 }
2955
2956 hi3c->pXferData = pXferData;
2957 hi3c->State = HAL_I3C_STATE_BUSY_TX;
2958
2959
2960 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
2961 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
2962 {
2963 /* Set byte treatment function pointer */
2964 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
2965 }
2966 else
2967 {
2968 /* Set word treatment function pointer */
2969 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
2970 }
2971
2972 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
2973 of I3C interrupt handle execution before current process unlock */
2974
2975 /* Enable Tx process interrupts */
2976 I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT);
2977
2978 /* Initiate a Start condition */
2979 LL_I3C_RequestTransfer(hi3c->Instance);
2980 }
2981 }
2982
2983 return status;
2984 }
2985
2986 #if defined(HAL_DMA_MODULE_ENABLED)
2987 /**
2988 * @brief Controller transmit direct write or a broadcast CCC command in DMA mode.
2989 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
2990 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
2991 * multiple transmission frames.
2992 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
2993 * for the specified I3C.
2994 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
2995 * (control buffer, data buffer and status buffer).
2996 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
2997 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
2998 */
HAL_I3C_Ctrl_TransmitCCC_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)2999 HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC_DMA(I3C_HandleTypeDef *hi3c,
3000 I3C_XferTypeDef *pXferData)
3001 {
3002 HAL_StatusTypeDef control_dma_status;
3003 HAL_StatusTypeDef tx_dma_status = HAL_OK;
3004 HAL_I3C_StateTypeDef handle_state;
3005 HAL_StatusTypeDef status = HAL_OK;
3006 uint32_t size_align_word;
3007
3008 /* check on the handle */
3009 if (hi3c == NULL)
3010 {
3011 status = HAL_ERROR;
3012 }
3013 else
3014 {
3015 /* Check the instance and the mode parameters */
3016 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
3017 assert_param(IS_I3C_MODE(hi3c->Mode));
3018
3019 /* Get I3C handle state */
3020 handle_state = hi3c->State;
3021
3022 /* Check on user parameters */
3023 if ((pXferData == NULL) ||
3024 ((hi3c->TxXferCount != 0U) && (pXferData->TxBuf.pBuffer == NULL)))
3025 {
3026 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
3027 status = HAL_ERROR;
3028 }
3029 /* Check on hdmatx and hdmacr handle */
3030 else if ((hi3c->hdmatx == NULL) || (hi3c->hdmacr == NULL))
3031 {
3032 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
3033 status = HAL_ERROR;
3034 }
3035 /* check on the Mode */
3036 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
3037 {
3038 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
3039 status = HAL_ERROR;
3040 }
3041 /* check on the State */
3042 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
3043 {
3044 status = HAL_BUSY;
3045 }
3046 else
3047 {
3048 /* Set handle transfer parameters */
3049 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
3050 hi3c->XferISR = I3C_Ctrl_Tx_DMA_ISR;
3051 hi3c->pXferData = pXferData;
3052 hi3c->State = HAL_I3C_STATE_BUSY_TX;
3053
3054 /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/
3055 /* Set the I3C DMA transfer complete callback */
3056 hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt;
3057
3058 /* Set the DMA error callback */
3059 hi3c->hdmacr->XferErrorCallback = I3C_DMAError;
3060
3061 /* Set the unused DMA callbacks to NULL */
3062 hi3c->hdmacr->XferHalfCpltCallback = NULL;
3063 hi3c->hdmacr->XferAbortCallback = NULL;
3064
3065 /* assert that DMA source and destination width are configured in word */
3066 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth));
3067 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth));
3068
3069 /* Enable the control data DMA channel */
3070 control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer,
3071 (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U));
3072
3073 /*------------------------------------ I3C DMA channel for the Tx Data -----------------------------------------*/
3074 /* Check if Tx counter different from zero */
3075 if (hi3c->TxXferCount != 0U)
3076 {
3077 /* Set the I3C DMA transfer complete callback */
3078 hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt;
3079
3080 /* Set the DMA error callback */
3081 hi3c->hdmatx->XferErrorCallback = I3C_DMAError;
3082
3083 /* Set the unused DMA callbacks to NULL */
3084 hi3c->hdmatx->XferHalfCpltCallback = NULL;
3085 hi3c->hdmatx->XferAbortCallback = NULL;
3086
3087 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
3088 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
3089 {
3090 /* assert that DMA source and destination width are configured in byte */
3091 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
3092 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth));
3093
3094 /* Enable the Tx data DMA channel */
3095 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
3096 (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size);
3097 }
3098 else
3099 {
3100 /* assert that DMA source and destination width are configured in word */
3101 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
3102 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth));
3103
3104 /* Check to align data size in words */
3105 if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U)
3106 {
3107 /* Keep the same size */
3108 size_align_word = hi3c->pXferData->TxBuf.Size;
3109 }
3110 else
3111 {
3112 /* Modify size to be multiple of 4 */
3113 size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U));
3114 }
3115
3116 /* Enable the Tx data DMA channel */
3117 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
3118 (uint32_t)&hi3c->Instance->TDWR, size_align_word);
3119 }
3120 }
3121
3122 /* Check if DMA process is well started */
3123 if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK))
3124 {
3125 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
3126 of I3C interrupt handle execution before current process unlock */
3127
3128 /* Enable Tx process interrupts */
3129 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
3130
3131 /* Update the number of remaining data bytes */
3132 hi3c->ControlXferCount = 0U;
3133
3134 /* Enable control DMA Request */
3135 LL_I3C_EnableDMAReq_Control(hi3c->Instance);
3136
3137 /* Check if Tx counter different from zero */
3138 if (hi3c->TxXferCount != 0U)
3139 {
3140 /* Update the number of remaining data bytes */
3141 hi3c->TxXferCount = 0U;
3142
3143 /* Enable Tx data DMA Request */
3144 LL_I3C_EnableDMAReq_TX(hi3c->Instance);
3145 }
3146
3147 /* Initiate a Start condition */
3148 LL_I3C_RequestTransfer(hi3c->Instance);
3149 }
3150 else
3151 {
3152 /* Set callback to NULL if DMA started */
3153 if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK)
3154 {
3155 hi3c->hdmacr->XferCpltCallback = NULL;
3156 hi3c->hdmacr->XferErrorCallback = NULL;
3157 }
3158
3159 /* Set callback to NULL if DMA started */
3160 if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK)
3161 {
3162 hi3c->hdmatx->XferCpltCallback = NULL;
3163 hi3c->hdmatx->XferErrorCallback = NULL;
3164 }
3165
3166 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
3167 status = HAL_ERROR;
3168
3169 /* Update handle state parameter */
3170 I3C_StateUpdate(hi3c);
3171 }
3172 }
3173 }
3174
3175 return status;
3176 }
3177 #endif /* HAL_DMA_MODULE_ENABLED */
3178
3179 /**
3180 * @brief Controller transmit direct read CCC command in polling mode.
3181 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
3182 * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor.
3183 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
3184 * for the specified I3C.
3185 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
3186 * (control buffer, data buffer and status buffer).
3187 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
3188 * @param timeout : [IN] Timeout duration in millisecond.
3189 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
3190 */
HAL_I3C_Ctrl_ReceiveCCC(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)3191 HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC(I3C_HandleTypeDef *hi3c,
3192 I3C_XferTypeDef *pXferData,
3193 uint32_t timeout)
3194 {
3195 uint32_t tickstart;
3196 uint32_t exit_condition;
3197 HAL_StatusTypeDef status = HAL_OK;
3198 HAL_I3C_StateTypeDef handle_state;
3199
3200 /* check on the handle */
3201 if (hi3c == NULL)
3202 {
3203 status = HAL_ERROR;
3204 }
3205 else
3206 {
3207 /* Check the instance and the mode parameters */
3208 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
3209 assert_param(IS_I3C_MODE(hi3c->Mode));
3210
3211 /* Get I3C handle state */
3212 handle_state = hi3c->State;
3213
3214 /* Check on user parameters */
3215 if ((pXferData == NULL) ||
3216 (pXferData->RxBuf.pBuffer == NULL) ||
3217 ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U)))
3218 {
3219 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
3220 status = HAL_ERROR;
3221 }
3222 /* check on the Mode */
3223 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
3224 {
3225 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
3226 status = HAL_ERROR;
3227 }
3228 /* check on the State */
3229 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
3230 {
3231 status = HAL_BUSY;
3232 }
3233 else
3234 {
3235 /* Set handle transfer parameters */
3236 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
3237 hi3c->State = HAL_I3C_STATE_BUSY_RX;
3238 hi3c->pXferData = pXferData;
3239 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
3240
3241 /* Check on CCC defining byte */
3242 if (hi3c->TxXferCount != 0U)
3243 {
3244 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
3245 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
3246 {
3247 /* Set byte treatment function pointer */
3248 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
3249 }
3250 else
3251 {
3252 /* Set word treatment function pointer */
3253 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
3254 }
3255 }
3256
3257 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
3258 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
3259 {
3260 /* Set byte treatment function pointer */
3261 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
3262 }
3263 else
3264 {
3265 /* Set word treatment function pointer */
3266 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
3267 }
3268
3269 /* Init tickstart for timeout management */
3270 tickstart = HAL_GetTick();
3271
3272 /* Check on control FIFO enable/disable state */
3273 if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U)
3274 {
3275 /* Initiate a Start condition */
3276 LL_I3C_RequestTransfer(hi3c->Instance);
3277 }
3278 else
3279 {
3280 /* Decrement remaining control buffer data counter */
3281 hi3c->ControlXferCount--;
3282
3283 /* Initiate a start condition by writing in the CR register */
3284 WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer);
3285
3286 /* Increment Buffer pointer */
3287 hi3c->pXferData->CtrlBuf.pBuffer++;
3288 }
3289
3290 /* Do while until FC (Frame Complete) is set or timeout */
3291 do
3292 {
3293 /* Call control data treatment function */
3294 I3C_ControlDataTreatment(hi3c);
3295
3296 if (hi3c->TxXferCount != 0U)
3297 {
3298 /* Call transmit treatment function */
3299 hi3c->ptrTxFunc(hi3c);
3300 }
3301
3302 /* Call receive treatment function */
3303 hi3c->ptrRxFunc(hi3c);
3304
3305 /* Check for the timeout */
3306 if (timeout != HAL_MAX_DELAY)
3307 {
3308 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
3309 {
3310 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
3311 status = HAL_TIMEOUT;
3312
3313 break;
3314 }
3315 }
3316
3317 if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U))
3318 {
3319 /* Clear frame complete flag */
3320 LL_I3C_ClearFlag_FC(hi3c->Instance);
3321
3322 /* Then Initiate a Start condition */
3323 LL_I3C_RequestTransfer(hi3c->Instance);
3324 }
3325
3326 /* Calculate exit_condition value based on Frame complete and error flags */
3327 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
3328 } while ((exit_condition == 0U) ||
3329 ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U)));
3330
3331 /* Clear frame complete flag */
3332 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
3333 {
3334 LL_I3C_ClearFlag_FC(hi3c->Instance);
3335 }
3336
3337 /* Check if all data bytes are received */
3338 if ((hi3c->RxXferCount != 0U) && (status == HAL_OK))
3339 {
3340 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
3341 status = HAL_ERROR;
3342 }
3343
3344 /* Check on error flag */
3345 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
3346 {
3347 /* Clear error flag */
3348 LL_I3C_ClearFlag_ERR(hi3c->Instance);
3349
3350 /* Update handle error code parameter */
3351 I3C_GetErrorSources(hi3c);
3352
3353 /* Update returned status value */
3354 status = HAL_ERROR;
3355 }
3356
3357 /* At the end of Rx process update state to Previous state */
3358 I3C_StateUpdate(hi3c);
3359 }
3360 }
3361
3362 return status;
3363 }
3364
3365 /**
3366 * @brief Controller transmit direct read CCC command in interrupt mode.
3367 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
3368 * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor.
3369 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
3370 * for the specified I3C.
3371 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
3372 * (control buffer, data buffer and status buffer).
3373 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
3374 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
3375 */
HAL_I3C_Ctrl_ReceiveCCC_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)3376 HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC_IT(I3C_HandleTypeDef *hi3c,
3377 I3C_XferTypeDef *pXferData)
3378 {
3379 HAL_I3C_StateTypeDef handle_state;
3380 HAL_StatusTypeDef status = HAL_OK;
3381
3382 /* check on the handle */
3383 if (hi3c == NULL)
3384 {
3385 status = HAL_ERROR;
3386 }
3387 else
3388 {
3389 /* Check the instance and the mode parameters */
3390 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
3391 assert_param(IS_I3C_MODE(hi3c->Mode));
3392
3393 /* Get I3C handle state */
3394 handle_state = hi3c->State;
3395
3396 /* Check on user parameters */
3397 if ((pXferData == NULL) ||
3398 (pXferData->RxBuf.pBuffer == NULL) ||
3399 ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U)))
3400 {
3401 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
3402 status = HAL_ERROR;
3403 }
3404 /* check on the Mode */
3405 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
3406 {
3407 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
3408 status = HAL_ERROR;
3409 }
3410 /* check on the State */
3411 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
3412 {
3413 status = HAL_BUSY;
3414 }
3415 else
3416 {
3417 /* Set handle transfer parameters */
3418 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
3419 if (handle_state == HAL_I3C_STATE_LISTEN)
3420 {
3421 hi3c->XferISR = I3C_Ctrl_Rx_Listen_Event_ISR;
3422 }
3423 else
3424 {
3425 hi3c->XferISR = I3C_Ctrl_Rx_ISR;
3426 }
3427 hi3c->pXferData = pXferData;
3428 hi3c->RxXferCount = pXferData->RxBuf.Size;
3429 hi3c->State = HAL_I3C_STATE_BUSY_RX;
3430
3431 /* Check on CCC defining byte */
3432 if (hi3c->TxXferCount != 0U)
3433 {
3434 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
3435 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
3436 {
3437 /* Set byte treatment function pointer */
3438 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
3439 }
3440 else
3441 {
3442 /* Set word treatment function pointer */
3443 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
3444 }
3445 }
3446
3447 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
3448 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
3449 {
3450 /* Set byte treatment function pointer */
3451 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
3452 }
3453 else
3454 {
3455 /* Set word treatment function pointer */
3456 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
3457 }
3458
3459 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
3460 of I3C interrupt handle execution before current process unlock */
3461
3462 /* Enable Rx process interrupts */
3463 I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
3464
3465 /* Initiate a Start condition */
3466 LL_I3C_RequestTransfer(hi3c->Instance);
3467
3468 }
3469 }
3470
3471 return status;
3472 }
3473
3474 #if defined(HAL_DMA_MODULE_ENABLED)
3475 /**
3476 * @brief Controller transmit direct read CCC command in DMA mode.
3477 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
3478 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
3479 * for the specified I3C.
3480 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
3481 * (control buffer, data buffer and status buffer).
3482 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
3483 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
3484 */
HAL_I3C_Ctrl_ReceiveCCC_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)3485 HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC_DMA(I3C_HandleTypeDef *hi3c,
3486 I3C_XferTypeDef *pXferData)
3487 {
3488 HAL_I3C_StateTypeDef handle_state;
3489 HAL_StatusTypeDef status = HAL_OK;
3490 HAL_StatusTypeDef control_dma_status;
3491 HAL_StatusTypeDef tx_dma_status = HAL_OK;
3492 HAL_StatusTypeDef rx_dma_status = HAL_OK;
3493 uint32_t size_align_word;
3494
3495 /* check on the handle */
3496 if (hi3c == NULL)
3497 {
3498 status = HAL_ERROR;
3499 }
3500 else
3501 {
3502 /* Check the instance and the mode parameters */
3503 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
3504 assert_param(IS_I3C_MODE(hi3c->Mode));
3505
3506 /* Get I3C handle state */
3507 handle_state = hi3c->State;
3508
3509 /* Check on user parameters */
3510 if ((pXferData == NULL) ||
3511 (pXferData->RxBuf.pBuffer == NULL) ||
3512 ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U)))
3513 {
3514 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
3515 status = HAL_ERROR;
3516 }
3517 /* Check on hdmarx and hdmacr handle */
3518 else if ((hi3c->hdmarx == NULL) || (hi3c->hdmacr == NULL))
3519 {
3520 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
3521 status = HAL_ERROR;
3522 }
3523 else if ((hi3c->TxXferCount != 0U) && (hi3c->hdmatx == NULL))
3524 {
3525 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
3526 status = HAL_ERROR;
3527 }
3528 /* check on the Mode */
3529 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
3530 {
3531 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
3532 status = HAL_ERROR;
3533 }
3534 /* check on the State */
3535 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
3536 {
3537 status = HAL_BUSY;
3538 }
3539 else
3540 {
3541 /* Set handle transfer parameters */
3542 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
3543 hi3c->XferISR = I3C_Ctrl_Rx_DMA_ISR;
3544 hi3c->pXferData = pXferData;
3545 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
3546 hi3c->State = HAL_I3C_STATE_BUSY_RX;
3547
3548 /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/
3549 /* Set the I3C DMA transfer complete callback */
3550 hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt;
3551
3552 /* Set the DMA error callback */
3553 hi3c->hdmacr->XferErrorCallback = I3C_DMAError;
3554
3555 /* Set the unused DMA callbacks to NULL */
3556 hi3c->hdmacr->XferHalfCpltCallback = NULL;
3557 hi3c->hdmacr->XferAbortCallback = NULL;
3558
3559 /* assert that DMA source and destination width are configured in word */
3560 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth));
3561 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth));
3562
3563 /* Enable the control data DMA channel */
3564 control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer,
3565 (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U));
3566
3567 /*------------------------------------ I3C DMA channel for defining byte ---------------------------------------*/
3568 /* Check if Tx counter different from zero */
3569 if (hi3c->TxXferCount != 0U)
3570 {
3571 /* Set the I3C DMA transfer complete callback */
3572 hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt;
3573
3574 /* Set the DMA error callback */
3575 hi3c->hdmatx->XferErrorCallback = I3C_DMAError;
3576
3577 /* Set the unused DMA callbacks to NULL */
3578 hi3c->hdmatx->XferHalfCpltCallback = NULL;
3579 hi3c->hdmatx->XferAbortCallback = NULL;
3580
3581 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
3582 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
3583 {
3584 /* assert that DMA source and destination width are configured in byte */
3585 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
3586 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth));
3587
3588 /* Enable the Tx data DMA channel */
3589 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
3590 (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size);
3591 }
3592 else
3593 {
3594 /* assert that DMA source and destination width are configured in word */
3595 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
3596 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth));
3597
3598 /* Modify size to be multiple of 4 */
3599 size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U));
3600
3601 /* Enable the Tx data DMA channel */
3602 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
3603 (uint32_t)&hi3c->Instance->TDWR, size_align_word);
3604 }
3605 }
3606 /*------------------------------------ I3C DMA channel for the Rx Data -----------------------------------------*/
3607 /* Check if Rx counter different from zero */
3608 if (hi3c->RxXferCount != 0U)
3609 {
3610 /* Set the I3C DMA transfer complete callback */
3611 hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt;
3612
3613 /* Set the DMA error callback */
3614 hi3c->hdmarx->XferErrorCallback = I3C_DMAError;
3615
3616 /* Set the unused DMA callbacks to NULL */
3617 hi3c->hdmarx->XferHalfCpltCallback = NULL;
3618 hi3c->hdmarx->XferAbortCallback = NULL;
3619
3620 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
3621 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
3622 {
3623 /* assert that DMA source and destination width are configured in byte */
3624 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
3625 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth));
3626
3627 /* Enable the Rx data DMA channel */
3628 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR,
3629 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size);
3630 }
3631 else
3632 {
3633 /* assert that DMA source and destination width are configured in word */
3634 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
3635 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth));
3636
3637 /* Check to align data size in words */
3638 if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U)
3639 {
3640 /* Keep the same size */
3641 size_align_word = hi3c->pXferData->RxBuf.Size;
3642 }
3643 else
3644 {
3645 /* Modify size to be multiple of 4 */
3646 size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U));
3647 }
3648
3649 /* Enable the Rx data DMA channel */
3650 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR,
3651 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word);
3652 }
3653 }
3654
3655 /* Check if DMA process is well started */
3656 if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK) && (rx_dma_status == HAL_OK))
3657 {
3658 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
3659 of I3C interrupt handle execution before current process unlock */
3660
3661 /* Enable Rx process interrupts */
3662 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
3663
3664 /* Update the number of remaining data bytes */
3665 hi3c->ControlXferCount = 0U;
3666
3667 /* Enable control DMA Request */
3668 LL_I3C_EnableDMAReq_Control(hi3c->Instance);
3669
3670 /* Check if Tx counter different from zero */
3671 if (hi3c->TxXferCount != 0U)
3672 {
3673 /* Update the number of remaining data bytes */
3674 hi3c->TxXferCount = 0U;
3675
3676 /* Enable Tx data DMA Request */
3677 LL_I3C_EnableDMAReq_TX(hi3c->Instance);
3678 }
3679
3680 /* Check if Rx counter different from zero */
3681 if (hi3c->RxXferCount != 0U)
3682 {
3683 /* Update the number of remaining data bytes */
3684 hi3c->RxXferCount = 0U;
3685
3686 /* Enable Rx data DMA Request */
3687 LL_I3C_EnableDMAReq_RX(hi3c->Instance);
3688 }
3689
3690 /* Initiate a Start condition */
3691 LL_I3C_RequestTransfer(hi3c->Instance);
3692 }
3693 else
3694 {
3695 /* Set callback to NULL if DMA started */
3696 if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK)
3697 {
3698 hi3c->hdmacr->XferCpltCallback = NULL;
3699 hi3c->hdmacr->XferErrorCallback = NULL;
3700 }
3701
3702 /* Set callback to NULL if DMA started */
3703 if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK)
3704 {
3705 hi3c->hdmatx->XferCpltCallback = NULL;
3706 hi3c->hdmatx->XferErrorCallback = NULL;
3707 }
3708
3709 /* Set callback to NULL if DMA started */
3710 if (HAL_DMA_Abort(hi3c->hdmarx) == HAL_OK)
3711 {
3712 hi3c->hdmarx->XferCpltCallback = NULL;
3713 hi3c->hdmarx->XferErrorCallback = NULL;
3714 }
3715
3716 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
3717 status = HAL_ERROR;
3718
3719 /* Update handle state parameter */
3720 I3C_StateUpdate(hi3c);
3721 }
3722 }
3723 }
3724
3725 return status;
3726 }
3727 #endif /* HAL_DMA_MODULE_ENABLED */
3728
3729 /**
3730 * @brief Controller private write in polling mode.
3731 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
3732 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
3733 * multiple transmission frames.
3734 * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor.
3735 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
3736 * for the specified I3C.
3737 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
3738 * (control buffer, data buffer and status buffer).
3739 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
3740 * @param timeout : [IN] Timeout duration in millisecond.
3741 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
3742 */
HAL_I3C_Ctrl_Transmit(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)3743 HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit(I3C_HandleTypeDef *hi3c,
3744 I3C_XferTypeDef *pXferData,
3745 uint32_t timeout)
3746 {
3747 uint32_t tickstart;
3748 uint32_t exit_condition;
3749 HAL_StatusTypeDef status = HAL_OK;
3750 HAL_I3C_StateTypeDef handle_state;
3751
3752 /* check on the handle */
3753 if (hi3c == NULL)
3754 {
3755 status = HAL_ERROR;
3756 }
3757 else
3758 {
3759 /* Check the instance and the mode parameters */
3760 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
3761 assert_param(IS_I3C_MODE(hi3c->Mode));
3762
3763 /* Get I3C handle state */
3764 handle_state = hi3c->State;
3765
3766 /* Check on user parameters */
3767 if ((pXferData == NULL) ||
3768 ((hi3c->TxXferCount != 0U) && (pXferData->TxBuf.pBuffer == NULL)))
3769 {
3770 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
3771 status = HAL_ERROR;
3772 }
3773 /* check on the Mode */
3774 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
3775 {
3776 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
3777 status = HAL_ERROR;
3778 }
3779 /* check on the State */
3780 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
3781 {
3782 status = HAL_BUSY;
3783 }
3784 else
3785 {
3786 /* Set handle transfer parameters */
3787 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
3788 hi3c->State = HAL_I3C_STATE_BUSY_TX;
3789 hi3c->pXferData = pXferData;
3790
3791 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
3792 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
3793 {
3794 /* Set byte treatment function pointer */
3795 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
3796 }
3797 else
3798 {
3799 /* Set word treatment function pointer */
3800 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
3801 }
3802
3803 /* Init tickstart for timeout management */
3804 tickstart = HAL_GetTick();
3805
3806 /* Check on control FIFO enable/disable state */
3807 if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U)
3808 {
3809 /* Initiate a Start condition */
3810 LL_I3C_RequestTransfer(hi3c->Instance);
3811 }
3812 else
3813 {
3814 /* Decrement remaining control buffer data counter */
3815 hi3c->ControlXferCount--;
3816
3817 /* Initiate a start condition by writing in the CR register */
3818 WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer);
3819
3820 /* Increment Buffer pointer */
3821 hi3c->pXferData->CtrlBuf.pBuffer++;
3822 }
3823
3824 /* Do while until FC (Frame Complete) is set or timeout */
3825 do
3826 {
3827 /* Call control data treatment function */
3828 I3C_ControlDataTreatment(hi3c);
3829
3830 /* Call transmit treatment function */
3831 hi3c->ptrTxFunc(hi3c);
3832
3833 /* Check for the timeout */
3834 if (timeout != HAL_MAX_DELAY)
3835 {
3836 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
3837 {
3838 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
3839 status = HAL_TIMEOUT;
3840
3841 break;
3842 }
3843 }
3844
3845 if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U))
3846 {
3847 /* Clear frame complete flag */
3848 LL_I3C_ClearFlag_FC(hi3c->Instance);
3849
3850 /* Then Initiate a Start condition */
3851 LL_I3C_RequestTransfer(hi3c->Instance);
3852 }
3853
3854 /* Calculate exit_condition value based on Frame complete and error flags */
3855 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
3856 } while ((exit_condition == 0U) ||
3857 ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U)));
3858
3859 /* Clear frame complete flag */
3860 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
3861 {
3862 LL_I3C_ClearFlag_FC(hi3c->Instance);
3863 }
3864
3865 /* Check if all data bytes are transmitted */
3866 if ((hi3c->TxXferCount != 0U) && (status == HAL_OK))
3867 {
3868 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
3869 status = HAL_ERROR;
3870 }
3871
3872 /* Check on error flag */
3873 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
3874 {
3875 /* Clear error flag */
3876 LL_I3C_ClearFlag_ERR(hi3c->Instance);
3877
3878 /* Update handle error code parameter */
3879 I3C_GetErrorSources(hi3c);
3880
3881 /* Update returned status value */
3882 status = HAL_ERROR;
3883 }
3884
3885 /* At the end of Tx process update state to Previous state */
3886 I3C_StateUpdate(hi3c);
3887 }
3888 }
3889
3890 return status;
3891 }
3892
3893 /**
3894 * @brief Controller private write in interrupt mode.
3895 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
3896 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
3897 * multiple transmission frames.
3898 * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor.
3899 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
3900 * for the specified I3C.
3901 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
3902 * (control buffer, data buffer and status buffer).
3903 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
3904 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
3905 */
HAL_I3C_Ctrl_Transmit_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)3906 HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit_IT(I3C_HandleTypeDef *hi3c,
3907 I3C_XferTypeDef *pXferData)
3908 {
3909 HAL_I3C_StateTypeDef handle_state;
3910 HAL_StatusTypeDef status = HAL_OK;
3911
3912 /* check on the handle */
3913 if (hi3c == NULL)
3914 {
3915 status = HAL_ERROR;
3916 }
3917 else
3918 {
3919 /* Check the instance and the mode parameters */
3920 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
3921 assert_param(IS_I3C_MODE(hi3c->Mode));
3922
3923 /* Get I3C handle state */
3924 handle_state = hi3c->State;
3925
3926 /* Check on user parameters */
3927 if ((pXferData == NULL) ||
3928 ((hi3c->TxXferCount != 0U) && (pXferData->TxBuf.pBuffer == NULL)))
3929 {
3930 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
3931 status = HAL_ERROR;
3932 }
3933 /* check on the Mode */
3934 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
3935 {
3936 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
3937 status = HAL_ERROR;
3938 }
3939 /* check on the State */
3940 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
3941 {
3942 status = HAL_BUSY;
3943 }
3944 else
3945 {
3946 /* Set handle transfer parameters */
3947 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
3948 if (handle_state == HAL_I3C_STATE_LISTEN)
3949 {
3950 hi3c->XferISR = I3C_Ctrl_Tx_Listen_Event_ISR;
3951 }
3952 else
3953 {
3954 hi3c->XferISR = I3C_Ctrl_Tx_ISR;
3955 }
3956 hi3c->pXferData = pXferData;
3957 hi3c->State = HAL_I3C_STATE_BUSY_TX;
3958
3959 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
3960 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
3961 {
3962 /* Set byte treatment function pointer */
3963 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
3964 }
3965 else
3966 {
3967 /* Set word treatment function pointer */
3968 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
3969 }
3970
3971 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
3972 of I3C interrupt handle execution before current process unlock */
3973
3974 /* Enable Tx process interrupts */
3975 I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT);
3976
3977 /* Initiate a Start condition */
3978 LL_I3C_RequestTransfer(hi3c->Instance);
3979 }
3980 }
3981
3982 return status;
3983 }
3984
3985 #if defined(HAL_DMA_MODULE_ENABLED)
3986 /**
3987 * @brief Controller private write in DMA mode.
3988 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
3989 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
3990 * multiple transmission frames.
3991 * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor.
3992 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
3993 * for the specified I3C.
3994 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
3995 * (control buffer, data buffer and status buffer).
3996 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
3997 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
3998 */
HAL_I3C_Ctrl_Transmit_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)3999 HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit_DMA(I3C_HandleTypeDef *hi3c,
4000 I3C_XferTypeDef *pXferData)
4001 {
4002 HAL_StatusTypeDef control_dma_status;
4003 HAL_StatusTypeDef tx_dma_status = HAL_OK;
4004 HAL_I3C_StateTypeDef handle_state;
4005 HAL_StatusTypeDef status = HAL_OK;
4006 uint32_t size_align_word;
4007
4008 /* check on the handle */
4009 if (hi3c == NULL)
4010 {
4011 status = HAL_ERROR;
4012 }
4013 else
4014 {
4015 /* Check the instance and the mode parameters */
4016 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
4017 assert_param(IS_I3C_MODE(hi3c->Mode));
4018
4019 /* Get I3C handle state */
4020 handle_state = hi3c->State;
4021
4022 /* Check on user parameters */
4023 if ((pXferData == NULL) ||
4024 ((hi3c->TxXferCount != 0U) && (pXferData->TxBuf.pBuffer == NULL)))
4025 {
4026 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
4027 status = HAL_ERROR;
4028 }
4029 /* Check on hdmatx and hdmacr handle */
4030 else if ((hi3c->hdmatx == NULL) || (hi3c->hdmacr == NULL))
4031 {
4032 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
4033 status = HAL_ERROR;
4034 }
4035 /* check on the Mode */
4036 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
4037 {
4038 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
4039 status = HAL_ERROR;
4040 }
4041 /* check on the State */
4042 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
4043 {
4044 status = HAL_BUSY;
4045 }
4046 else
4047 {
4048 /* Set handle transfer parameters */
4049 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
4050 hi3c->XferISR = I3C_Ctrl_Tx_DMA_ISR;
4051 hi3c->State = HAL_I3C_STATE_BUSY_TX;
4052 hi3c->pXferData = pXferData;
4053
4054 /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/
4055 /* Set the I3C DMA transfer complete callback */
4056 hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt;
4057
4058 /* Set the DMA error callback */
4059 hi3c->hdmacr->XferErrorCallback = I3C_DMAError;
4060
4061 /* Set the unused DMA callbacks to NULL */
4062 hi3c->hdmacr->XferHalfCpltCallback = NULL;
4063 hi3c->hdmacr->XferAbortCallback = NULL;
4064
4065 /* assert that DMA source and destination width are configured in word */
4066 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth));
4067 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth));
4068
4069 /* Enable the control data DMA channel */
4070 control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer,
4071 (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U));
4072
4073 /*------------------------------------ I3C DMA channel for the Tx Data -----------------------------------------*/
4074 /* Check if Tx counter different from zero */
4075 if (hi3c->TxXferCount != 0U)
4076 {
4077 /* Set the I3C DMA transfer complete callback */
4078 hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt;
4079
4080 /* Set the DMA error callback */
4081 hi3c->hdmatx->XferErrorCallback = I3C_DMAError;
4082
4083 /* Set the unused DMA callbacks to NULL */
4084 hi3c->hdmatx->XferHalfCpltCallback = NULL;
4085 hi3c->hdmatx->XferAbortCallback = NULL;
4086
4087 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
4088 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
4089 {
4090 /* assert that DMA source and destination width are configured in byte */
4091 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
4092 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth));
4093
4094 /* Enable the Tx data DMA channel */
4095 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
4096 (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size);
4097 }
4098 else
4099 {
4100 /* assert that DMA source and destination width are configured in word */
4101 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
4102 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth));
4103
4104 /* Check to align data size in words */
4105 if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U)
4106 {
4107 /* Keep the same size */
4108 size_align_word = hi3c->pXferData->TxBuf.Size;
4109 }
4110 else
4111 {
4112 /* Modify size to be multiple of 4 */
4113 size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U));
4114 }
4115
4116 /* Enable the Tx data DMA channel */
4117 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
4118 (uint32_t)&hi3c->Instance->TDWR, size_align_word);
4119 }
4120 }
4121
4122 /* Check if DMA process is well started */
4123 if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK))
4124 {
4125 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
4126 of I3C interrupt handle execution before current process unlock */
4127
4128 /* Enable Tx process interrupts */
4129 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
4130
4131 /* Update the number of remaining data bytes */
4132 hi3c->ControlXferCount = 0U;
4133
4134 /* Enable control DMA Request */
4135 LL_I3C_EnableDMAReq_Control(hi3c->Instance);
4136
4137 /* Check if Tx counter different from zero */
4138 if (hi3c->TxXferCount != 0U)
4139 {
4140 /* Update the number of remaining data bytes */
4141 hi3c->TxXferCount = 0U;
4142
4143 /* Enable Tx data DMA Request */
4144 LL_I3C_EnableDMAReq_TX(hi3c->Instance);
4145 }
4146
4147 /* Initiate a Start condition */
4148 LL_I3C_RequestTransfer(hi3c->Instance);
4149 }
4150 else
4151 {
4152 /* Set callback to NULL if DMA started */
4153 if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK)
4154 {
4155 hi3c->hdmacr->XferCpltCallback = NULL;
4156 hi3c->hdmacr->XferErrorCallback = NULL;
4157 }
4158
4159 /* Set callback to NULL if DMA started */
4160 if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK)
4161 {
4162 hi3c->hdmatx->XferCpltCallback = NULL;
4163 hi3c->hdmatx->XferErrorCallback = NULL;
4164 }
4165
4166 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
4167 status = HAL_ERROR;
4168
4169 /* Update handle state parameter */
4170 I3C_StateUpdate(hi3c);
4171 }
4172 }
4173 }
4174
4175 return status;
4176 }
4177 #endif /* HAL_DMA_MODULE_ENABLED */
4178
4179 /**
4180 * @brief Controller private read in polling mode.
4181 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
4182 * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor.
4183 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
4184 * for the specified I3C.
4185 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
4186 * (control buffer, data buffer and status buffer).
4187 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
4188 * @param timeout : [IN] Timeout duration in millisecond.
4189 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
4190 */
HAL_I3C_Ctrl_Receive(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)4191 HAL_StatusTypeDef HAL_I3C_Ctrl_Receive(I3C_HandleTypeDef *hi3c,
4192 I3C_XferTypeDef *pXferData,
4193 uint32_t timeout)
4194 {
4195 uint32_t tickstart;
4196 uint32_t exit_condition;
4197 HAL_StatusTypeDef status = HAL_OK;
4198 HAL_I3C_StateTypeDef handle_state;
4199
4200 /* check on the handle */
4201 if (hi3c == NULL)
4202 {
4203 status = HAL_ERROR;
4204 }
4205 else
4206 {
4207 /* Check the instance and the mode parameters */
4208 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
4209 assert_param(IS_I3C_MODE(hi3c->Mode));
4210
4211 /* Get I3C handle state */
4212 handle_state = hi3c->State;
4213
4214 /* Check on user parameters */
4215 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL))
4216 {
4217 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
4218 status = HAL_ERROR;
4219 }
4220 /* check on the Mode */
4221 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
4222 {
4223 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
4224 status = HAL_ERROR;
4225 }
4226 /* check on the State */
4227 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
4228 {
4229 status = HAL_BUSY;
4230 }
4231 else
4232 {
4233 /* Set handle transfer parameters */
4234 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
4235 hi3c->State = HAL_I3C_STATE_BUSY_RX;
4236 hi3c->pXferData = pXferData;
4237 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
4238
4239 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
4240 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
4241 {
4242 /* Set byte treatment function pointer */
4243 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
4244 }
4245 else
4246 {
4247 /* Set word treatment function pointer */
4248 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
4249 }
4250
4251 /* Init tickstart for timeout management */
4252 tickstart = HAL_GetTick();
4253
4254 /* Check on control FIFO enable/disable state */
4255 if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U)
4256 {
4257 /* Initiate a Start condition */
4258 LL_I3C_RequestTransfer(hi3c->Instance);
4259 }
4260 else
4261 {
4262 /* Decrement remaining control buffer data counter */
4263 hi3c->ControlXferCount--;
4264
4265 /* Initiate a start condition by writing in the CR register */
4266 WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer);
4267
4268 /* Increment Buffer pointer */
4269 hi3c->pXferData->CtrlBuf.pBuffer++;
4270 }
4271
4272 /* Do while until FC (Frame Complete) is set or timeout */
4273 do
4274 {
4275 /* Call control data treatment function */
4276 I3C_ControlDataTreatment(hi3c);
4277
4278 /* Call receive treatment function */
4279 hi3c->ptrRxFunc(hi3c);
4280
4281 /* Check for the timeout */
4282 if (timeout != HAL_MAX_DELAY)
4283 {
4284 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
4285 {
4286 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
4287 status = HAL_TIMEOUT;
4288
4289 break;
4290 }
4291 }
4292
4293 if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U))
4294 {
4295 /* Clear frame complete flag */
4296 LL_I3C_ClearFlag_FC(hi3c->Instance);
4297
4298 /* Then Initiate a Start condition */
4299 LL_I3C_RequestTransfer(hi3c->Instance);
4300 }
4301
4302 /* Calculate exit_condition value based on Frame complete and error flags */
4303 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
4304 } while ((exit_condition == 0U) ||
4305 ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U)));
4306
4307 /* Clear frame complete flag */
4308 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
4309 {
4310 LL_I3C_ClearFlag_FC(hi3c->Instance);
4311 }
4312
4313 /* Check if all data bytes are received */
4314 if ((hi3c->RxXferCount != 0U) && (status == HAL_OK))
4315 {
4316 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
4317 status = HAL_ERROR;
4318 }
4319
4320 /* Check on error flag */
4321 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
4322 {
4323 /* Clear error flag */
4324 LL_I3C_ClearFlag_ERR(hi3c->Instance);
4325
4326 /* Update handle error code parameter */
4327 I3C_GetErrorSources(hi3c);
4328
4329 /* Update returned status value */
4330 status = HAL_ERROR;
4331 }
4332
4333 /* At the end of Rx process update state to Previous state */
4334 I3C_StateUpdate(hi3c);
4335 }
4336 }
4337
4338 return status;
4339 }
4340
4341 /**
4342 * @brief Controller private read in interrupt mode.
4343 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
4344 * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor.
4345 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
4346 * for the specified I3C.
4347 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
4348 * (control buffer, data buffer and status buffer).
4349 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
4350 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
4351 */
HAL_I3C_Ctrl_Receive_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)4352 HAL_StatusTypeDef HAL_I3C_Ctrl_Receive_IT(I3C_HandleTypeDef *hi3c,
4353 I3C_XferTypeDef *pXferData)
4354 {
4355 HAL_I3C_StateTypeDef handle_state;
4356 HAL_StatusTypeDef status = HAL_OK;
4357
4358 /* check on the handle */
4359 if (hi3c == NULL)
4360 {
4361 status = HAL_ERROR;
4362 }
4363 else
4364 {
4365 /* Check the instance and the mode parameters */
4366 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
4367 assert_param(IS_I3C_MODE(hi3c->Mode));
4368
4369 /* Get I3C handle state */
4370 handle_state = hi3c->State;
4371
4372 /* Check on user parameters */
4373 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL))
4374 {
4375 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
4376 status = HAL_ERROR;
4377 }
4378 /* check on the Mode */
4379 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
4380 {
4381 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
4382 status = HAL_ERROR;
4383 }
4384 /* check on the State */
4385 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
4386 {
4387 status = HAL_BUSY;
4388 }
4389 else
4390 {
4391 /* Set handle transfer parameters */
4392 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
4393 if (handle_state == HAL_I3C_STATE_LISTEN)
4394 {
4395 hi3c->XferISR = I3C_Ctrl_Rx_Listen_Event_ISR;
4396 }
4397 else
4398 {
4399 hi3c->XferISR = I3C_Ctrl_Rx_ISR;
4400 }
4401 hi3c->pXferData = pXferData;
4402 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
4403 hi3c->State = HAL_I3C_STATE_BUSY_RX;
4404
4405 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
4406 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
4407 {
4408 /* Set byte treatment function pointer */
4409 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
4410 }
4411 else
4412 {
4413 /* Set word treatment function pointer */
4414 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
4415 }
4416
4417 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
4418 of I3C interrupt handle execution before current process unlock */
4419
4420 /* Enable Rx process interrupts */
4421 I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_IT);
4422
4423 /* Initiate a Start condition */
4424 LL_I3C_RequestTransfer(hi3c->Instance);
4425 }
4426 }
4427
4428 return status;
4429 }
4430
4431 #if defined(HAL_DMA_MODULE_ENABLED)
4432 /**
4433 * @brief Controller private read in DMA mode.
4434 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
4435 * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor.
4436 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
4437 * for the specified I3C.
4438 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
4439 * (control buffer, data buffer and status buffer).
4440 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
4441 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
4442 */
HAL_I3C_Ctrl_Receive_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)4443 HAL_StatusTypeDef HAL_I3C_Ctrl_Receive_DMA(I3C_HandleTypeDef *hi3c,
4444 I3C_XferTypeDef *pXferData)
4445 {
4446 HAL_StatusTypeDef control_dma_status;
4447 HAL_StatusTypeDef rx_dma_status = HAL_OK;
4448 HAL_I3C_StateTypeDef handle_state;
4449 HAL_StatusTypeDef status = HAL_OK;
4450 uint32_t size_align_word;
4451
4452 /* check on the handle */
4453 if (hi3c == NULL)
4454 {
4455 status = HAL_ERROR;
4456 }
4457 else
4458 {
4459 /* Check the instance and the mode parameters */
4460 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
4461 assert_param(IS_I3C_MODE(hi3c->Mode));
4462
4463 /* Get I3C handle state */
4464 handle_state = hi3c->State;
4465
4466 /* Check on user parameters */
4467 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL))
4468 {
4469 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
4470 status = HAL_ERROR;
4471 }
4472 /* Check on hdmarx and hdmacr handle */
4473 else if ((hi3c->hdmarx == NULL) || (hi3c->hdmacr == NULL))
4474 {
4475 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
4476 status = HAL_ERROR;
4477 }
4478 /* check on the Mode */
4479 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
4480 {
4481 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
4482 status = HAL_ERROR;
4483 }
4484 /* check on the State */
4485 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
4486 {
4487 status = HAL_BUSY;
4488 }
4489 else
4490 {
4491 /* Set handle transfer parameters */
4492 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
4493 hi3c->XferISR = I3C_Ctrl_Rx_DMA_ISR;
4494 hi3c->pXferData = pXferData;
4495 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
4496 hi3c->State = HAL_I3C_STATE_BUSY_RX;
4497
4498 /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/
4499 /* Set the I3C DMA transfer complete callback */
4500 hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt;
4501
4502 /* Set the DMA error callback */
4503 hi3c->hdmacr->XferErrorCallback = I3C_DMAError;
4504
4505 /* Set the unused DMA callbacks to NULL */
4506 hi3c->hdmacr->XferHalfCpltCallback = NULL;
4507 hi3c->hdmacr->XferAbortCallback = NULL;
4508
4509 /* assert that DMA source and destination width are configured in word */
4510 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth));
4511 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth));
4512
4513 /* Enable the control data DMA channel */
4514 control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer,
4515 (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U));
4516
4517 /*------------------------------------ I3C DMA channel for the Rx Data -----------------------------------------*/
4518 /* Check if Rx counter different from zero */
4519 if (hi3c->RxXferCount != 0U)
4520 {
4521 /* Set the I3C DMA transfer complete callback */
4522 hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt;
4523
4524 /* Set the DMA error callback */
4525 hi3c->hdmarx->XferErrorCallback = I3C_DMAError;
4526
4527 /* Set the unused DMA callbacks to NULL */
4528 hi3c->hdmarx->XferHalfCpltCallback = NULL;
4529 hi3c->hdmarx->XferAbortCallback = NULL;
4530
4531 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
4532 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
4533 {
4534 /* assert that DMA source and destination width are configured in byte */
4535 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
4536 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth));
4537
4538 /* Enable the Rx data DMA channel */
4539 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR,
4540 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size);
4541 }
4542 else
4543 {
4544 /* assert that DMA source and destination width are configured in word */
4545 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
4546 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth));
4547
4548 /* Check to align data size in words */
4549 if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U)
4550 {
4551 /* Keep the same size */
4552 size_align_word = hi3c->pXferData->RxBuf.Size;
4553 }
4554 else
4555 {
4556 /* Modify size to be multiple of 4 */
4557 size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U));
4558 }
4559
4560 /* Enable the Rx data DMA channel */
4561 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR,
4562 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word);
4563 }
4564 }
4565
4566 /* Check if DMA process is well started */
4567 if ((control_dma_status == HAL_OK) && (rx_dma_status == HAL_OK))
4568 {
4569 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
4570 of I3C interrupt handle execution before current process unlock */
4571
4572 /* Enable Rx process interrupts */
4573 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
4574
4575 /* Update the number of remaining data bytes */
4576 hi3c->ControlXferCount = 0U;
4577
4578 /* Enable control DMA Request */
4579 LL_I3C_EnableDMAReq_Control(hi3c->Instance);
4580
4581 /* Check if Rx counter different from zero */
4582 if (hi3c->RxXferCount != 0U)
4583 {
4584 /* Update the number of remaining data bytes */
4585 hi3c->RxXferCount = 0U;
4586
4587 /* Enable Rx data DMA Request */
4588 LL_I3C_EnableDMAReq_RX(hi3c->Instance);
4589 }
4590
4591 /* Initiate a Start condition */
4592 LL_I3C_RequestTransfer(hi3c->Instance);
4593 }
4594 else
4595 {
4596 /* Set callback to NULL if DMA started */
4597 if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK)
4598 {
4599 hi3c->hdmacr->XferCpltCallback = NULL;
4600 hi3c->hdmacr->XferErrorCallback = NULL;
4601 }
4602
4603 /* Set callback to NULL if DMA started */
4604 if (HAL_DMA_Abort(hi3c->hdmarx) == HAL_OK)
4605 {
4606 hi3c->hdmarx->XferCpltCallback = NULL;
4607 hi3c->hdmarx->XferErrorCallback = NULL;
4608 }
4609
4610 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
4611 status = HAL_ERROR;
4612
4613 /* Update handle state parameter */
4614 I3C_StateUpdate(hi3c);
4615 }
4616
4617 }
4618 }
4619
4620 return status;
4621 }
4622 #endif /* HAL_DMA_MODULE_ENABLED */
4623
4624 /**
4625 * @brief Controller multiple Direct CCC Command, I3C private or I2C transfer in interrupt mode.
4626 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
4627 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
4628 * multiple transmission frames.
4629 * @note This function must be called to transfer read/write I3C or I2C private data or a direct read/write CCC.
4630 * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor.
4631 * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor.
4632 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
4633 * for the specified I3C.
4634 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmit and receive
4635 * buffers (control buffer, data buffers and status buffer).
4636 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
4637 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
4638 */
HAL_I3C_Ctrl_MultipleTransfer_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)4639 HAL_StatusTypeDef HAL_I3C_Ctrl_MultipleTransfer_IT(I3C_HandleTypeDef *hi3c,
4640 I3C_XferTypeDef *pXferData)
4641 {
4642 HAL_I3C_StateTypeDef handle_state;
4643 HAL_StatusTypeDef status = HAL_OK;
4644
4645 /* check on the handle */
4646 if (hi3c == NULL)
4647 {
4648 status = HAL_ERROR;
4649 }
4650 else
4651 {
4652 /* Check the instance and the mode parameters */
4653 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
4654 assert_param(IS_I3C_MODE(hi3c->Mode));
4655
4656 /* Get I3C handle state */
4657 handle_state = hi3c->State;
4658
4659 /* Check on user parameters */
4660 if ((pXferData == NULL) ||
4661 ((pXferData->RxBuf.pBuffer == NULL) && (hi3c->RxXferCount != 0U)) ||
4662 ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U)))
4663 {
4664 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
4665 status = HAL_ERROR;
4666 }
4667 /* check on the Mode */
4668 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
4669 {
4670 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
4671 status = HAL_ERROR;
4672 }
4673 /* check on the State */
4674 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
4675 {
4676 status = HAL_BUSY;
4677 }
4678 else
4679 {
4680 /* Set handle transfer parameters */
4681 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
4682 if (handle_state == HAL_I3C_STATE_LISTEN)
4683 {
4684 hi3c->XferISR = I3C_Ctrl_Multiple_Xfer_Listen_Event_ISR;
4685 }
4686 else
4687 {
4688 hi3c->XferISR = I3C_Ctrl_Multiple_Xfer_ISR;
4689 }
4690 hi3c->pXferData = pXferData;
4691 hi3c->TxXferCount = hi3c->pXferData->TxBuf.Size;
4692 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
4693 hi3c->State = HAL_I3C_STATE_BUSY_TX_RX;
4694
4695 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
4696 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
4697 {
4698 /* Set byte treatment function pointer */
4699 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
4700 }
4701 else
4702 {
4703 /* Set word treatment function pointer */
4704 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
4705 }
4706
4707 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
4708 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
4709 {
4710 /* Set byte treatment function pointer */
4711 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
4712 }
4713 else
4714 {
4715 /* Set word treatment function pointer */
4716 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
4717 }
4718
4719 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
4720 of I3C interrupt handle execution before current process unlock */
4721
4722 /* Enable Tx and Rx process interrupts */
4723 I3C_Enable_IRQ(hi3c, (I3C_XFER_CONTROLLER_TX_IT | I3C_XFER_CONTROLLER_RX_IT));
4724
4725 /* Initiate a Start condition */
4726 LL_I3C_RequestTransfer(hi3c->Instance);
4727 }
4728 }
4729 return status;
4730 }
4731
4732 #if defined(HAL_DMA_MODULE_ENABLED)
4733 /**
4734 * @brief Controller multiple Direct CCC Command, I3C private or I2C transfer in DMA mode.
4735 * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer.
4736 * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
4737 * multiple transmission frames.
4738 * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor.
4739 * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor.
4740 * @note This function must be called to transfer read/write private data or a direct read/write CCC command.
4741 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
4742 * for the specified I3C.
4743 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmit and receive
4744 * buffers(control buffer, data buffer and status buffer).
4745 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
4746 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
4747 */
HAL_I3C_Ctrl_MultipleTransfer_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)4748 HAL_StatusTypeDef HAL_I3C_Ctrl_MultipleTransfer_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
4749 {
4750 HAL_StatusTypeDef control_dma_status;
4751 HAL_StatusTypeDef tx_dma_status = HAL_OK;
4752 HAL_StatusTypeDef rx_dma_status = HAL_OK;
4753 HAL_I3C_StateTypeDef handle_state;
4754 HAL_StatusTypeDef status = HAL_OK;
4755 uint32_t size_align_word;
4756
4757 /* check on the handle */
4758 if (hi3c == NULL)
4759 {
4760 status = HAL_ERROR;
4761 }
4762 else
4763 {
4764 /* Check the instance and the mode parameters */
4765 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
4766 assert_param(IS_I3C_MODE(hi3c->Mode));
4767
4768 /* Get I3C handle state */
4769 handle_state = hi3c->State;
4770
4771 /* Check on user parameters */
4772 if ((pXferData == NULL) ||
4773 ((pXferData->RxBuf.pBuffer == NULL) && (hi3c->RxXferCount != 0U)) ||
4774 ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U)))
4775 {
4776 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
4777 status = HAL_ERROR;
4778 }
4779 /* Check on hdmatx, hdmarx and hdmacr handle */
4780 else if ((hi3c->hdmatx == NULL) || (hi3c->hdmacr == NULL) || (hi3c->hdmarx == NULL))
4781 {
4782 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
4783 status = HAL_ERROR;
4784 }
4785 /* check on the Mode */
4786 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
4787 {
4788 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
4789 status = HAL_ERROR;
4790 }
4791 /* check on the State */
4792 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
4793 {
4794 status = HAL_BUSY;
4795 }
4796 else
4797 {
4798 /* Set handle transfer parameters */
4799 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
4800 hi3c->XferISR = I3C_Ctrl_Multiple_Xfer_DMA_ISR;
4801 hi3c->pXferData = pXferData;
4802 hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size;
4803 hi3c->TxXferCount = hi3c->pXferData->TxBuf.Size;
4804 hi3c->State = HAL_I3C_STATE_BUSY_TX_RX;
4805
4806 /*------------------------------------ I3C DMA channel for Control Data -------------------------------------*/
4807 /* Set the I3C DMA transfer complete callback */
4808 hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt;
4809
4810 /* Set the DMA error callback */
4811 hi3c->hdmacr->XferErrorCallback = I3C_DMAError;
4812
4813 /* Set the unused DMA callbacks to NULL */
4814 hi3c->hdmacr->XferHalfCpltCallback = NULL;
4815 hi3c->hdmacr->XferAbortCallback = NULL;
4816
4817 /* assert that DMA source and destination width are configured in word */
4818 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth));
4819 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth));
4820
4821 /* Enable the control data DMA channel */
4822 control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer,
4823 (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U));
4824
4825 /*------------------------------------ I3C DMA channel for the Rx Data --------------------------------*/
4826 /* Check if Rx counter different from zero */
4827 if (hi3c->RxXferCount != 0U)
4828 {
4829 /* Set the I3C DMA transfer complete callback */
4830 hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt;
4831
4832 /* Set the DMA error callback */
4833 hi3c->hdmarx->XferErrorCallback = I3C_DMAError;
4834
4835 /* Set the unused DMA callbacks to NULL */
4836 hi3c->hdmarx->XferHalfCpltCallback = NULL;
4837 hi3c->hdmarx->XferAbortCallback = NULL;
4838
4839 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
4840 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
4841 {
4842 /* assert that DMA source and destination width are configured in byte */
4843 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
4844 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth));
4845
4846 /* Enable the Rx data DMA channel */
4847 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR,
4848 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size);
4849 }
4850 else
4851 {
4852 /* assert that DMA source and destination width are configured in word */
4853 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
4854 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth));
4855
4856 /* Check to align data size in words */
4857 if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U)
4858 {
4859 /* Keep the same size */
4860 size_align_word = hi3c->pXferData->RxBuf.Size;
4861 }
4862 else
4863 {
4864 /* Modify size to be multiple of 4 */
4865 size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U));
4866 }
4867
4868 /* Enable the Rx data DMA channel */
4869 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR,
4870 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word);
4871 }
4872 }
4873
4874 /*------------------------------------ I3C DMA channel for the Tx Data --------------------------------*/
4875 /* Check if Tx counter different from zero */
4876 if (hi3c->TxXferCount != 0U)
4877 {
4878 /* Set the I3C DMA transfer complete callback */
4879 hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt;
4880
4881 /* Set the DMA error callback */
4882 hi3c->hdmatx->XferErrorCallback = I3C_DMAError;
4883
4884 /* Set the unused DMA callbacks to NULL */
4885 hi3c->hdmatx->XferHalfCpltCallback = NULL;
4886 hi3c->hdmatx->XferAbortCallback = NULL;
4887
4888 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
4889 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
4890 {
4891 /* assert that DMA source and destination width are configured in byte */
4892 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
4893 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth));
4894
4895 /* Enable the Tx data DMA channel */
4896 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
4897 (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size);
4898 }
4899 else
4900 {
4901 /* assert that DMA source and destination width are configured in word */
4902 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
4903 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth));
4904
4905 /* Check to align data size in words */
4906 if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U)
4907 {
4908 /* Keep the same size */
4909 size_align_word = hi3c->pXferData->TxBuf.Size;
4910 }
4911 else
4912 {
4913 /* Modify size to be multiple of 4 */
4914 size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U));
4915 }
4916
4917 /* Enable the Tx data DMA channel */
4918 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
4919 (uint32_t)&hi3c->Instance->TDWR, size_align_word);
4920 }
4921 }
4922
4923 /* Check if DMA process is well started */
4924 if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK) && (rx_dma_status == HAL_OK))
4925 {
4926 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
4927 of I3C interrupt handle execution before current process unlock */
4928
4929 /* Enable Tx process interrupts */
4930 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
4931
4932 /* Update the number of remaining data bytes */
4933 hi3c->ControlXferCount = 0U;
4934
4935 /* Enable control DMA Request */
4936 LL_I3C_EnableDMAReq_Control(hi3c->Instance);
4937
4938 /* Check if Rx counter different from zero */
4939 if (hi3c->RxXferCount != 0U)
4940 {
4941 /* Update the number of remaining data bytes */
4942 hi3c->RxXferCount = 0U;
4943
4944 /* Enable Rx data DMA Request */
4945 LL_I3C_EnableDMAReq_RX(hi3c->Instance);
4946 }
4947
4948 /* Check if Tx counter different from zero */
4949 if (hi3c->TxXferCount != 0U)
4950 {
4951 /* Update the number of remaining data bytes */
4952 hi3c->TxXferCount = 0U;
4953
4954 /* Enable Tx data DMA Request */
4955 LL_I3C_EnableDMAReq_TX(hi3c->Instance);
4956 }
4957
4958 /* Initiate a Start condition */
4959 LL_I3C_RequestTransfer(hi3c->Instance);
4960 }
4961 else
4962 {
4963 /* Set callback to NULL if DMA started */
4964 if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK)
4965 {
4966 hi3c->hdmacr->XferCpltCallback = NULL;
4967 hi3c->hdmacr->XferErrorCallback = NULL;
4968 }
4969
4970 /* Set callback to NULL if DMA started */
4971 if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK)
4972 {
4973 hi3c->hdmatx->XferCpltCallback = NULL;
4974 hi3c->hdmatx->XferErrorCallback = NULL;
4975 }
4976
4977 /* Set callback to NULL if DMA started */
4978 if (HAL_DMA_Abort(hi3c->hdmarx) == HAL_OK)
4979 {
4980 hi3c->hdmarx->XferCpltCallback = NULL;
4981 hi3c->hdmarx->XferErrorCallback = NULL;
4982 }
4983
4984 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
4985 status = HAL_ERROR;
4986
4987 /* Update handle state parameter */
4988 I3C_StateUpdate(hi3c);
4989 }
4990 }
4991 }
4992 return status;
4993 }
4994 #endif /* HAL_DMA_MODULE_ENABLED */
4995
4996 /**
4997 * @brief Controller assign dynamic address (send a broadcast ENTDAA CCC command) in polling mode.
4998 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
4999 * information for the specified I3C.
5000 * @param target_payload : [IN/OUT] Pointer to the returned target payload value.
5001 * @param dynOption : [IN] Parameter indicates the Dynamic address assignment option.
5002 * It can be one value of @ref I3C_DYNAMIC_ADDRESS_OPTION_DEFINITION.
5003 * @param timeout : [IN] Timeout duration in millisecond.
5004 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5005 */
HAL_I3C_Ctrl_DynAddrAssign(I3C_HandleTypeDef * hi3c,uint64_t * target_payload,uint32_t dynOption,uint32_t timeout)5006 HAL_StatusTypeDef HAL_I3C_Ctrl_DynAddrAssign(I3C_HandleTypeDef *hi3c,
5007 uint64_t *target_payload,
5008 uint32_t dynOption,
5009 uint32_t timeout)
5010 {
5011 uint32_t tickstart;
5012 HAL_I3C_StateTypeDef handle_state;
5013 HAL_StatusTypeDef status = HAL_OK;
5014
5015 /* check on parameters */
5016 assert_param(IS_I3C_ENTDAA_OPTION(dynOption));
5017
5018 /* check on the handle */
5019 if (hi3c == NULL)
5020 {
5021 status = HAL_ERROR;
5022 }
5023 else
5024 {
5025 /* Check the instance and the mode parameters */
5026 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5027 assert_param(IS_I3C_MODE(hi3c->Mode));
5028
5029 /* Get I3C handle state */
5030 handle_state = hi3c->State;
5031
5032 if (target_payload == NULL)
5033 {
5034 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5035 status = HAL_ERROR;
5036 }
5037 /* check on the Mode */
5038 else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
5039 {
5040 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5041 status = HAL_ERROR;
5042 }
5043 else
5044 {
5045 /* Launch a RSTDAA procedure before launch ENTDAA */
5046 if ((dynOption == I3C_RSTDAA_THEN_ENTDAA) &&
5047 ((handle_state == HAL_I3C_STATE_READY) || (handle_state == HAL_I3C_STATE_LISTEN)))
5048 {
5049 /* Set handle transfer parameters */
5050 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5051 hi3c->State = HAL_I3C_STATE_BUSY_DAA;
5052
5053 /* Init tickstart for timeout management */
5054 tickstart = HAL_GetTick();
5055
5056 /* Enable arbitration header */
5057 LL_I3C_EnableArbitrationHeader(hi3c->Instance);
5058
5059 /* Write CCC information in the control register */
5060 LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_RSTDAA, 0U, LL_I3C_GENERATE_STOP);
5061
5062 /* Wait Frame completion flag */
5063 status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_FCF, RESET, timeout, tickstart);
5064
5065 /* Clear frame complete flag */
5066 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
5067 {
5068 LL_I3C_ClearFlag_FC(hi3c->Instance);
5069 }
5070
5071 /* Check on error flag */
5072 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
5073 {
5074 /* Clear error flag */
5075 LL_I3C_ClearFlag_ERR(hi3c->Instance);
5076
5077 /* Update handle error code parameter */
5078 I3C_GetErrorSources(hi3c);
5079
5080 status = HAL_ERROR;
5081 }
5082
5083 /* Update handle state parameter */
5084 I3C_StateUpdate(hi3c);
5085 }
5086
5087 if (status == HAL_OK)
5088 {
5089 /* check on the State */
5090 if ((handle_state == HAL_I3C_STATE_READY) || (handle_state == HAL_I3C_STATE_LISTEN) ||
5091 (handle_state == HAL_I3C_STATE_BUSY_DAA))
5092 {
5093 /* Check on the state */
5094 if (handle_state != HAL_I3C_STATE_BUSY_DAA)
5095 {
5096 /* Set handle transfer parameters */
5097 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5098 hi3c->State = HAL_I3C_STATE_BUSY_DAA;
5099
5100 /* Init tickstart for timeout management */
5101 tickstart = HAL_GetTick();
5102
5103 /* Enable arbitration header */
5104 LL_I3C_EnableArbitrationHeader(hi3c->Instance);
5105
5106 /* Write CCC information in the control register */
5107 LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_ENTDAA, 0U, LL_I3C_GENERATE_STOP);
5108 }
5109 else
5110 {
5111 /* Init tickstart for timeout management */
5112 tickstart = HAL_GetTick();
5113 }
5114
5115 /* Wait frame complete flag or TX FIFO not full flag until timeout */
5116 status = I3C_WaitOnDAAUntilTimeout(hi3c, timeout, tickstart);
5117
5118 /* Check TX FIFO not full flag */
5119 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET)
5120 {
5121 /* Check on the Rx FIFO threshold to know the Rx treatment process : byte or word */
5122 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
5123 {
5124 /* For loop to get target payload */
5125 for (uint32_t index = 0U; index < 8U; index++)
5126 {
5127 /* Retrieve payload byte by byte */
5128 *target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData8(hi3c->Instance) << (index * 8U));
5129 }
5130 }
5131 else
5132 {
5133 /* Retrieve first 32 bits payload */
5134 *target_payload = (uint64_t)LL_I3C_ReceiveData32(hi3c->Instance);
5135
5136 /* Retrieve second 32 bits payload */
5137 *target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData32(hi3c->Instance) << 32U);
5138 }
5139
5140 status = HAL_BUSY;
5141 }
5142 /* Check on frame complete flag */
5143 else
5144 {
5145 /* Clear frame complete flag */
5146 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
5147 {
5148 /* Clear frame complete flag */
5149 LL_I3C_ClearFlag_FC(hi3c->Instance);
5150 }
5151 /* Update handle state parameter */
5152 I3C_StateUpdate(hi3c);
5153 }
5154 }
5155 else
5156 {
5157 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5158 status = HAL_ERROR;
5159 }
5160 }
5161 }
5162 }
5163
5164 return status;
5165 }
5166
5167 /**
5168 * @brief Controller assign dynamic address (send a broadcast ENTDAA CCC command) in interrupt mode.
5169 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5170 * for the specified I3C.
5171 * @param dynOption : [IN] Parameter indicates the Dynamic address assignment option.
5172 * It can be one value of @ref I3C_DYNAMIC_ADDRESS_OPTION_DEFINITION.
5173 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5174 */
HAL_I3C_Ctrl_DynAddrAssign_IT(I3C_HandleTypeDef * hi3c,uint32_t dynOption)5175 HAL_StatusTypeDef HAL_I3C_Ctrl_DynAddrAssign_IT(I3C_HandleTypeDef *hi3c, uint32_t dynOption)
5176 {
5177 HAL_I3C_StateTypeDef handle_state;
5178 HAL_StatusTypeDef status = HAL_OK;
5179
5180 /* check on parameters */
5181 assert_param(IS_I3C_ENTDAA_OPTION(dynOption));
5182
5183 /* check on the handle */
5184 if (hi3c == NULL)
5185 {
5186 status = HAL_ERROR;
5187 }
5188 else
5189 {
5190 /* Check the instance and the mode parameters */
5191 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5192 assert_param(IS_I3C_MODE(hi3c->Mode));
5193
5194 /* Get I3C handle state */
5195 handle_state = hi3c->State;
5196
5197 /* check on the Mode */
5198 if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
5199 {
5200 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5201 status = HAL_ERROR;
5202 }
5203 /* check on the State */
5204 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5205 {
5206 status = HAL_BUSY;
5207 }
5208 else
5209 {
5210 /* Set handle transfer parameters */
5211 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5212 hi3c->State = HAL_I3C_STATE_BUSY_DAA;
5213 hi3c->XferISR = I3C_Ctrl_DAA_ISR;
5214
5215 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
5216 of I3C interrupt handle execution before current process unlock */
5217
5218 /* Enable Dynamic Address Assignment process interrupts */
5219 I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_DAA_IT);
5220
5221 /* Enable arbitration header */
5222 LL_I3C_EnableArbitrationHeader(hi3c->Instance);
5223
5224 /* Launch a RSTDAA procedure before launch ENTDAA */
5225 if (dynOption == I3C_RSTDAA_THEN_ENTDAA)
5226 {
5227 /* Write RSTDAA CCC information in the control register */
5228 LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_RSTDAA, 0U, LL_I3C_GENERATE_RESTART);
5229 }
5230 else
5231 {
5232 /* Write ENTDAA CCC information in the control register */
5233 LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_ENTDAA, 0U, LL_I3C_GENERATE_STOP);
5234 }
5235 }
5236 }
5237
5238 return status;
5239 }
5240
5241 /**
5242 * @brief Controller set dynamic address.
5243 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5244 * for the specified I3C.
5245 * @param devAddress : [IN] Value of the dynamic address to be assigned.
5246 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5247 */
HAL_I3C_Ctrl_SetDynAddr(I3C_HandleTypeDef * hi3c,uint8_t devAddress)5248 HAL_StatusTypeDef HAL_I3C_Ctrl_SetDynAddr(I3C_HandleTypeDef *hi3c, uint8_t devAddress)
5249 {
5250 HAL_StatusTypeDef status = HAL_OK;
5251
5252 /* check on the handle */
5253 if (hi3c == NULL)
5254 {
5255 status = HAL_ERROR;
5256 }
5257 else
5258 {
5259 /* Check if Tx FIFO requests data */
5260 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET)
5261 {
5262 /* Write device address in the TDR register */
5263 LL_I3C_TransmitData8(hi3c->Instance, devAddress);
5264 }
5265 else
5266 {
5267 status = HAL_ERROR;
5268 }
5269 }
5270
5271 return status;
5272 }
5273
5274 /**
5275 * @brief Check if I3C target device is ready for communication.
5276 * @param hi3c : [IN] Pointer to a I3C_HandleTypeDef structure that contains
5277 * the configuration information for the specified I3C.
5278 * @param devAddress : [IN] Value of the device dynamic address.
5279 * @param trials : [IN] Number of trials
5280 * @param timeout : [IN] Timeout duration
5281 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5282 */
HAL_I3C_Ctrl_IsDeviceI3C_Ready(I3C_HandleTypeDef * hi3c,uint8_t devAddress,uint32_t trials,uint32_t timeout)5283 HAL_StatusTypeDef HAL_I3C_Ctrl_IsDeviceI3C_Ready(I3C_HandleTypeDef *hi3c,
5284 uint8_t devAddress,
5285 uint32_t trials,
5286 uint32_t timeout)
5287 {
5288 I3C_DeviceTypeDef device;
5289 HAL_StatusTypeDef status;
5290
5291 /* check on the handle */
5292 if (hi3c == NULL)
5293 {
5294 status = HAL_ERROR;
5295 }
5296 else
5297 {
5298 /* Check the instance and the mode parameters */
5299 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5300 assert_param(IS_I3C_MODE(hi3c->Mode));
5301
5302 /* Initiate a device address */
5303 device.Address = devAddress;
5304
5305 /* Initiate a message type */
5306 device.MessageType = LL_I3C_CONTROLLER_MTYPE_PRIVATE;
5307
5308 /* Check if the device is ready*/
5309 status = I3C_Ctrl_IsDevice_Ready(hi3c, &device, trials, timeout);
5310 }
5311
5312 return status;
5313 }
5314
5315 /**
5316 * @brief Check if I2C target device is ready for communication.
5317 * @param hi3c : [IN] Pointer to a I3C_HandleTypeDef structure that contains
5318 * the configuration information for the specified I3C.
5319 * @param devAddress : [IN] Value of the device dynamic address.
5320 * @param trials : [IN] Number of trials
5321 * @param timeout : [IN] Timeout duration
5322 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5323 */
HAL_I3C_Ctrl_IsDeviceI2C_Ready(I3C_HandleTypeDef * hi3c,uint8_t devAddress,uint32_t trials,uint32_t timeout)5324 HAL_StatusTypeDef HAL_I3C_Ctrl_IsDeviceI2C_Ready(I3C_HandleTypeDef *hi3c,
5325 uint8_t devAddress,
5326 uint32_t trials,
5327 uint32_t timeout)
5328 {
5329 I3C_DeviceTypeDef device;
5330 HAL_StatusTypeDef status;
5331
5332 /* check on the handle */
5333 if (hi3c == NULL)
5334 {
5335 status = HAL_ERROR;
5336 }
5337 else
5338 {
5339 /* Check the instance and the mode parameters */
5340 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5341 assert_param(IS_I3C_MODE(hi3c->Mode));
5342
5343 /* Initiate a device address */
5344 device.Address = devAddress;
5345
5346 /* Initiate a message type */
5347 device.MessageType = LL_I3C_CONTROLLER_MTYPE_LEGACY_I2C;
5348
5349 /* Check if the device is ready*/
5350 status = I3C_Ctrl_IsDevice_Ready(hi3c, &device, trials, timeout);
5351 }
5352
5353 return status;
5354 }
5355
5356 /**
5357 * @brief Controller generates arbitration (message header {S/Sr + 0x7E addr + W}) in polling mode.
5358 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains
5359 * the configuration information for the specified I3C.
5360 * @param timeout : [IN] Timeout duration
5361 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5362 */
HAL_I3C_Ctrl_GenerateArbitration(I3C_HandleTypeDef * hi3c,uint32_t timeout)5363 HAL_StatusTypeDef HAL_I3C_Ctrl_GenerateArbitration(I3C_HandleTypeDef *hi3c, uint32_t timeout)
5364 {
5365 HAL_StatusTypeDef status = HAL_OK;
5366 HAL_I3C_StateTypeDef handle_state;
5367 __IO uint32_t exit_condition;
5368 uint32_t tickstart;
5369
5370 /* check on the handle */
5371 if (hi3c == NULL)
5372 {
5373 status = HAL_ERROR;
5374 }
5375 else
5376 {
5377 /* Check the instance and the mode parameters */
5378 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5379 assert_param(IS_I3C_MODE(hi3c->Mode));
5380
5381 /* Get I3C handle state */
5382 handle_state = hi3c->State;
5383
5384 /* check on the Mode */
5385 if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
5386 {
5387 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5388 status = HAL_ERROR;
5389 }
5390 /* check on the State */
5391 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5392 {
5393 status = HAL_BUSY;
5394 }
5395 else
5396 {
5397 hi3c->State = HAL_I3C_STATE_BUSY;
5398
5399 /* Disable exit pattern */
5400 LL_I3C_DisableExitPattern(hi3c->Instance);
5401 /* Disable reset pattern */
5402 LL_I3C_DisableResetPattern(hi3c->Instance);
5403
5404 /* Write message control register */
5405 WRITE_REG(hi3c->Instance->CR, LL_I3C_CONTROLLER_MTYPE_HEADER | LL_I3C_GENERATE_STOP);
5406
5407 /* Calculate exit_condition value based on Frame complete and error flags */
5408 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
5409
5410 tickstart = HAL_GetTick();
5411
5412 while (exit_condition == 0U)
5413 {
5414 if (timeout != HAL_MAX_DELAY)
5415 {
5416 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
5417 {
5418 /* Update I3C error code */
5419 hi3c->ErrorCode |= HAL_I3C_ERROR_TIMEOUT;
5420 status = HAL_TIMEOUT;
5421
5422 break;
5423 }
5424 }
5425 /* Calculate exit_condition value based on Frame complete and error flags */
5426 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
5427 }
5428
5429 if (status == HAL_OK)
5430 {
5431 /* Check if the FCF flag has been set */
5432 if (__HAL_I3C_GET_FLAG(hi3c, I3C_EVR_FCF) == SET)
5433 {
5434 /* Clear frame complete flag */
5435 LL_I3C_ClearFlag_FC(hi3c->Instance);
5436 }
5437 else
5438 {
5439 /* Clear error flag */
5440 LL_I3C_ClearFlag_ERR(hi3c->Instance);
5441
5442 /* Update handle error code parameter */
5443 I3C_GetErrorSources(hi3c);
5444
5445 /* Update returned status value */
5446 status = HAL_ERROR;
5447 }
5448 }
5449
5450 /* At the end of Rx process update state to Previous state */
5451 I3C_StateUpdate(hi3c);
5452 }
5453 }
5454
5455 return status;
5456 }
5457
5458 /**
5459 * @}
5460 */
5461
5462 /** @defgroup I3C_Exported_Functions_Group6 Target operational functions.
5463 * @brief I3C target operational functions.
5464 *
5465 @verbatim
5466 =======================================================================================================================
5467 ##### Target operational functions #####
5468 =======================================================================================================================
5469 [..] This subsection provides a set of functions allowing to manage target I3C operation.
5470
5471 (+) Call the function HAL_I3C_Tgt_Transmit() to transmit private data in polling mode.
5472 (+) Call the function HAL_I3C_Tgt_Transmit_IT() to transmit private data in interrupt mode.
5473 (+) Call the function HAL_I3C_Tgt_Transmit_DMA() to transmit private data in DMA mode.
5474 (+) Call the function HAL_I3C_Tgt_Receive() to receive private data in polling mode.
5475 (+) Call the function HAL_I3C_Tgt_Receive_IT() to receive private data in interrupt mode.
5476 (+) Call the function HAL_I3C_Tgt_Receive_DMA() to receive private data in DMA mode.
5477 (+) Call the function HAL_I3C_Tgt_ControlRoleReq() to send a control-role request in polling mode.
5478 (+) Call the function HAL_I3C_Tgt_ControlRoleReq_IT() to send a control-role request in interrupt mode.
5479 (+) Call the function HAL_I3C_Tgt_HotJoinReq() to send a Hot-Join request in polling mode.
5480 (+) Call the function HAL_I3C_Tgt_HotJoinReq_IT() to send a Hot-Join request in interrupt mode.
5481 (+) Call the function HAL_I3C_Tgt_IBIReq() to send an IBI request in polling mode.
5482 (+) Call the function HAL_I3C_Tgt_IBIReq_IT() to send an IBI request in interrupt mode.
5483
5484 (+) Those functions are called only when mode is Target.
5485
5486 @endverbatim
5487 * @{
5488 */
5489
5490 /**
5491 * @brief Target transmit private data in polling mode.
5492 * @note Target FIFO preload data is forced within this API for timing purpose.
5493 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5494 * for the specified I3C.
5495 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
5496 * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data
5497 * to transmit in bytes (TxBuf.Size)).
5498 * @param timeout : [IN] Timeout duration in millisecond.
5499 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5500 */
HAL_I3C_Tgt_Transmit(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)5501 HAL_StatusTypeDef HAL_I3C_Tgt_Transmit(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout)
5502 {
5503 uint32_t tickstart;
5504 HAL_StatusTypeDef status = HAL_OK;
5505 HAL_I3C_StateTypeDef handle_state;
5506 uint32_t it_source;
5507
5508 /* check on the handle */
5509 if (hi3c == NULL)
5510 {
5511 status = HAL_ERROR;
5512 }
5513 else
5514 {
5515 /* Check the instance and the mode parameters */
5516 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5517 assert_param(IS_I3C_MODE(hi3c->Mode));
5518
5519 it_source = READ_REG(hi3c->Instance->IER);
5520
5521 /* Get I3C handle state */
5522 handle_state = hi3c->State;
5523
5524 /* Check on user parameters */
5525 if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U))
5526 {
5527 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5528 status = HAL_ERROR;
5529 }
5530 /* check on the Mode */
5531 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5532 {
5533 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5534 status = HAL_ERROR;
5535 }
5536 /* check on the State */
5537 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5538 {
5539 status = HAL_BUSY;
5540 }
5541 /* check if DEF or GRP CCC notifications are enabled */
5542 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5543 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5544 {
5545 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5546 status = HAL_ERROR;
5547 }
5548 /* Verify the dynamic address validity */
5549 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5550 {
5551 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5552 status = HAL_ERROR;
5553 }
5554 else
5555 {
5556 /* Set handle transfer parameters */
5557 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5558 hi3c->State = HAL_I3C_STATE_BUSY_TX;
5559 hi3c->pXferData = pXferData;
5560 hi3c->TxXferCount = pXferData->TxBuf.Size;
5561
5562 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
5563 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
5564 {
5565 /* Set byte treatment function pointer */
5566 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
5567 }
5568 else
5569 {
5570 /* Set word treatment function pointer */
5571 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
5572 }
5573
5574 /* Set Preload information */
5575 LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size);
5576
5577 /* Init tickstart for timeout management */
5578 tickstart = HAL_GetTick();
5579
5580 /* Do while until FC (Frame Complete) is set or timeout */
5581 do
5582 {
5583 /* Call transmit treatment function */
5584 hi3c->ptrTxFunc(hi3c);
5585
5586 /* Check for the Timeout */
5587 if (timeout != HAL_MAX_DELAY)
5588 {
5589 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
5590 {
5591 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
5592 status = HAL_TIMEOUT;
5593
5594 break;
5595 }
5596 }
5597 /* Exit loop on Frame complete or error flags */
5598 } while ((READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)) == 0U);
5599
5600 /* Clear frame complete flag */
5601 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
5602 {
5603 LL_I3C_ClearFlag_FC(hi3c->Instance);
5604 }
5605
5606 /* Check if all data bytes are transmitted */
5607 if ((LL_I3C_GetXferDataCount(hi3c->Instance) != hi3c->pXferData->TxBuf.Size) && (status == HAL_OK))
5608 {
5609 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
5610 status = HAL_ERROR;
5611 }
5612
5613 /* Check on error flag */
5614 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
5615 {
5616 /* Clear error flag */
5617 LL_I3C_ClearFlag_ERR(hi3c->Instance);
5618
5619 /* Update handle error code parameter */
5620 I3C_GetErrorSources(hi3c);
5621
5622 /* Update returned status value */
5623 status = HAL_ERROR;
5624 }
5625
5626 /* At the end of Tx process update state to Previous state */
5627 I3C_StateUpdate(hi3c);
5628 }
5629 }
5630
5631 return status;
5632 }
5633
5634 /**
5635 * @brief Target transmit private data in interrupt mode.
5636 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5637 * for the specified I3C.
5638 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
5639 * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data
5640 * to transmit in bytes (TxBuf.Size)).
5641 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5642 */
HAL_I3C_Tgt_Transmit_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)5643 HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
5644 {
5645 HAL_I3C_StateTypeDef handle_state;
5646 HAL_StatusTypeDef status = HAL_OK;
5647 uint32_t it_source;
5648
5649 /* check on the handle */
5650 if (hi3c == NULL)
5651 {
5652 status = HAL_ERROR;
5653 }
5654 else
5655 {
5656 /* Check the instance and the mode parameters */
5657 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5658 assert_param(IS_I3C_MODE(hi3c->Mode));
5659
5660 it_source = READ_REG(hi3c->Instance->IER);
5661
5662 /* Get I3C handle state */
5663 handle_state = hi3c->State;
5664
5665 /* Check on user parameters */
5666 if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U))
5667 {
5668 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5669 status = HAL_ERROR;
5670 }
5671 /* check on the Mode */
5672 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5673 {
5674 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5675 status = HAL_ERROR;
5676 }
5677 /* check on the State */
5678 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5679 {
5680 status = HAL_BUSY;
5681 }
5682 /* check if DEF and GRP CCC notifications are enabled */
5683 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5684 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5685 {
5686 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5687 status = HAL_ERROR;
5688 }
5689 /* Verify the dynamic address validity */
5690 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5691 {
5692 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5693
5694 status = HAL_ERROR;
5695 }
5696 else
5697 {
5698 /* Set handle transfer parameters */
5699 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5700 hi3c->State = HAL_I3C_STATE_BUSY_TX;
5701 hi3c->pXferData = pXferData;
5702 hi3c->TxXferCount = pXferData->TxBuf.Size;
5703 hi3c->XferISR = I3C_Tgt_Tx_ISR;
5704
5705 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
5706 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
5707 {
5708 /* Set byte treatment function pointer */
5709 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
5710 }
5711 else
5712 {
5713 /* Set word treatment function pointer */
5714 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
5715 }
5716
5717 /* Set Preload information */
5718 LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size);
5719
5720 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
5721 of I3C interrupt handle execution before current process unlock */
5722
5723 /* Enable Tx process interrupts */
5724 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_TX_IT);
5725 }
5726 }
5727
5728 return status;
5729 }
5730
5731 #if defined(HAL_DMA_MODULE_ENABLED)
5732 /**
5733 * @brief Target transmit private data in DMA mode.
5734 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5735 * for the specified I3C.
5736 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
5737 * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data
5738 * to transmit in bytes (TxBuf.Size)).
5739 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5740 */
HAL_I3C_Tgt_Transmit_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)5741 HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
5742 {
5743 HAL_StatusTypeDef tx_dma_status;
5744 HAL_I3C_StateTypeDef handle_state;
5745 HAL_StatusTypeDef status = HAL_OK;
5746 uint32_t size_align_word;
5747 uint32_t it_source;
5748
5749 /* check on the handle */
5750 if (hi3c == NULL)
5751 {
5752 status = HAL_ERROR;
5753 }
5754 else
5755 {
5756 /* Check the instance and the mode parameters */
5757 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5758 assert_param(IS_I3C_MODE(hi3c->Mode));
5759
5760 it_source = READ_REG(hi3c->Instance->IER);
5761
5762 /* Get I3C handle state */
5763 handle_state = hi3c->State;
5764
5765 /* Check on user parameters */
5766 if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U))
5767 {
5768 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5769 status = HAL_ERROR;
5770 }
5771 /* Check on hdmatx handle */
5772 else if (hi3c->hdmatx == NULL)
5773 {
5774 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
5775 status = HAL_ERROR;
5776 }
5777 /* check on the Mode */
5778 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5779 {
5780 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5781 status = HAL_ERROR;
5782 }
5783 /* check on the State */
5784 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5785 {
5786 status = HAL_BUSY;
5787 }
5788 /* check if DEF and GRP CCC notifications are enabled */
5789 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5790 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5791 {
5792 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5793 status = HAL_ERROR;
5794 }
5795 /* Verify the dynamic address validity */
5796 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5797 {
5798 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5799 status = HAL_ERROR;
5800 }
5801 else
5802 {
5803 /* Set handle transfer parameters */
5804 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5805 hi3c->State = HAL_I3C_STATE_BUSY_TX;
5806 hi3c->pXferData = pXferData;
5807 hi3c->TxXferCount = pXferData->TxBuf.Size;
5808 hi3c->XferISR = I3C_Tgt_Tx_DMA_ISR;
5809
5810 /* Set Preload information */
5811 LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size);
5812
5813 /*------------------------------------ I3C DMA channel for the Tx Data -----------------------------------------*/
5814 /* Set the I3C DMA transfer complete callback */
5815 hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt;
5816
5817 /* Set the DMA error callback */
5818 hi3c->hdmatx->XferErrorCallback = I3C_DMAError;
5819
5820 /* Set the unused DMA callbacks to NULL */
5821 hi3c->hdmatx->XferHalfCpltCallback = NULL;
5822 hi3c->hdmatx->XferAbortCallback = NULL;
5823
5824 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
5825 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
5826 {
5827 /* assert that DMA source and destination width are configured in byte */
5828 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
5829 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth));
5830
5831 /* Enable the Tx data DMA channel */
5832 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
5833 (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size);
5834 }
5835 else
5836 {
5837 /* assert that DMA source and destination width are configured in word */
5838 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
5839 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth));
5840
5841 /* Check to align data size in words */
5842 if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U)
5843 {
5844 /* Keep the same size */
5845 size_align_word = hi3c->pXferData->TxBuf.Size;
5846 }
5847 else
5848 {
5849 /* Modify size to be multiple of 4 */
5850 size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U));
5851 }
5852
5853 /* Enable the Tx data DMA channel */
5854 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
5855 (uint32_t)&hi3c->Instance->TDWR, size_align_word);
5856 }
5857
5858 /* Check if DMA process is well started */
5859 if (tx_dma_status == HAL_OK)
5860 {
5861 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
5862 of I3C interrupt handle execution before current process unlock */
5863
5864 /* Enable Tx process interrupts */
5865 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
5866
5867 /* Update the number of remaining data bytes */
5868 hi3c->TxXferCount = 0U;
5869
5870 /* Enable Tx data DMA Request */
5871 LL_I3C_EnableDMAReq_TX(hi3c->Instance);
5872 }
5873 else
5874 {
5875 /* Set callback to NULL if DMA started */
5876 hi3c->hdmatx->XferCpltCallback = NULL;
5877 hi3c->hdmatx->XferErrorCallback = NULL;
5878
5879 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
5880 status = HAL_ERROR;
5881
5882 /* Update handle state parameter */
5883 I3C_StateUpdate(hi3c);
5884 }
5885 }
5886 }
5887
5888 return status;
5889 }
5890 #endif /* HAL_DMA_MODULE_ENABLED */
5891
5892 /**
5893 * @brief Target receive private data in polling mode.
5894 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5895 * for the specified I3C.
5896 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
5897 * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data
5898 * to be received in bytes (RxBuf.Size)).
5899 * @param timeout : [IN] Timeout duration in millisecond.
5900 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5901 */
HAL_I3C_Tgt_Receive(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)5902 HAL_StatusTypeDef HAL_I3C_Tgt_Receive(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout)
5903 {
5904 uint32_t tickstart;
5905 HAL_StatusTypeDef status = HAL_OK;
5906 HAL_I3C_StateTypeDef handle_state;
5907 uint32_t it_source;
5908
5909 /* check on the handle */
5910 if (hi3c == NULL)
5911 {
5912 status = HAL_ERROR;
5913 }
5914 else
5915 {
5916 /* Check the instance and the mode parameters */
5917 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5918 assert_param(IS_I3C_MODE(hi3c->Mode));
5919
5920 it_source = READ_REG(hi3c->Instance->IER);
5921
5922 /* Get I3C handle state */
5923 handle_state = hi3c->State;
5924
5925 /* Check on user parameters */
5926 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U))
5927 {
5928 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5929 status = HAL_ERROR;
5930 }
5931 /* check on the Mode */
5932 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5933 {
5934 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5935 status = HAL_ERROR;
5936 }
5937 /* check on the State */
5938 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5939 {
5940 status = HAL_BUSY;
5941 }
5942 /* check if DEF and GRP CCC notifications are enabled */
5943 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5944 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5945 {
5946 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5947 status = HAL_ERROR;
5948 }
5949 /* Verify the dynamic address validity */
5950 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5951 {
5952 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5953 status = HAL_ERROR;
5954 }
5955 else
5956 {
5957 /* Set handle transfer parameters */
5958 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5959 hi3c->State = HAL_I3C_STATE_BUSY_RX;
5960 hi3c->pXferData = pXferData;
5961 hi3c->RxXferCount = pXferData->RxBuf.Size;
5962
5963 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
5964 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
5965 {
5966 /* Set byte treatment function pointer */
5967 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
5968 }
5969 else
5970 {
5971 /* Set word treatment function pointer */
5972 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
5973 }
5974
5975 /* Init tickstart for timeout management */
5976 tickstart = HAL_GetTick();
5977
5978 /* Do while until FC (Frame Complete) is set or timeout */
5979 do
5980 {
5981 if (hi3c->RxXferCount > 0U)
5982 {
5983 /* Call receive treatment function */
5984 hi3c->ptrRxFunc(hi3c);
5985 }
5986
5987 /* Check for the Timeout */
5988 if (timeout != HAL_MAX_DELAY)
5989 {
5990 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
5991 {
5992 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
5993 status = HAL_TIMEOUT;
5994
5995 break;
5996 }
5997 }
5998 /* Exit loop on Frame complete or error flags */
5999 } while ((READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)) == 0U);
6000
6001 /* Clear frame complete flag */
6002 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
6003 {
6004 LL_I3C_ClearFlag_FC(hi3c->Instance);
6005 }
6006
6007 /* Check if all data bytes are received */
6008 if ((LL_I3C_GetXferDataCount(hi3c->Instance) != hi3c->pXferData->RxBuf.Size) && (status == HAL_OK))
6009 {
6010 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
6011 status = HAL_ERROR;
6012 }
6013
6014 /* Check on error flag */
6015 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6016 {
6017 /* Clear error flag */
6018 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6019
6020 /* Update handle error code parameter */
6021 I3C_GetErrorSources(hi3c);
6022
6023 status = HAL_ERROR;
6024 }
6025
6026 /* At the end of Rx process update state to previous state */
6027 I3C_StateUpdate(hi3c);
6028 }
6029 }
6030
6031 return status;
6032 }
6033
6034 /**
6035 * @brief Target receive private data in interrupt mode.
6036 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6037 * for the specified I3C.
6038 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
6039 * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data
6040 * to be received in bytes (RxBuf.Size)).
6041 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6042 */
HAL_I3C_Tgt_Receive_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)6043 HAL_StatusTypeDef HAL_I3C_Tgt_Receive_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
6044 {
6045 HAL_I3C_StateTypeDef handle_state;
6046 HAL_StatusTypeDef status = HAL_OK;
6047 uint32_t it_source;
6048
6049 /* check on the handle */
6050 if (hi3c == NULL)
6051 {
6052 status = HAL_ERROR;
6053 }
6054 else
6055 {
6056 /* Check the instance and the mode parameters */
6057 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6058 assert_param(IS_I3C_MODE(hi3c->Mode));
6059
6060 it_source = READ_REG(hi3c->Instance->IER);
6061
6062 /* Get I3C handle state */
6063 handle_state = hi3c->State;
6064
6065 /* Check on user parameters */
6066 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U))
6067 {
6068 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6069 status = HAL_ERROR;
6070 }
6071 /* check on the Mode */
6072 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6073 {
6074 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6075 status = HAL_ERROR;
6076 }
6077 /* check on the State */
6078 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6079 {
6080 status = HAL_BUSY;
6081 }
6082 /* check if DEF and GRP CCC notifications are enabled */
6083 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
6084 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
6085 {
6086 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6087 status = HAL_ERROR;
6088 }
6089 /* Verify the dynamic address validity */
6090 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6091 {
6092 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6093 status = HAL_ERROR;
6094 }
6095 else
6096 {
6097 /* Set handle transfer parameters */
6098 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6099 hi3c->State = HAL_I3C_STATE_BUSY_RX;
6100 hi3c->pXferData = pXferData;
6101 hi3c->RxXferCount = pXferData->RxBuf.Size;
6102 hi3c->XferISR = I3C_Tgt_Rx_ISR;
6103
6104 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
6105 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
6106 {
6107 /* Set byte treatment function pointer */
6108 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
6109 }
6110 else
6111 {
6112 /* Set word treatment function pointer */
6113 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
6114 }
6115
6116 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
6117 of I3C interrupt handle execution before current process unlock */
6118
6119 /* Enable Rx process interrupts */
6120 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT);
6121 }
6122 }
6123
6124 return status;
6125 }
6126
6127 #if defined(HAL_DMA_MODULE_ENABLED)
6128 /**
6129 * @brief Target receive private data in DMA mode.
6130 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6131 * for the specified I3C.
6132 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
6133 * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data
6134 * to be received in bytes (RxBuf.Size)).
6135 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6136 */
HAL_I3C_Tgt_Receive_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)6137 HAL_StatusTypeDef HAL_I3C_Tgt_Receive_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
6138 {
6139 HAL_StatusTypeDef rx_dma_status;
6140 HAL_I3C_StateTypeDef handle_state;
6141 HAL_StatusTypeDef status = HAL_OK;
6142 uint32_t size_align_word;
6143 uint32_t it_source;
6144
6145 /* check on the handle */
6146 if (hi3c == NULL)
6147 {
6148 status = HAL_ERROR;
6149 }
6150 else
6151 {
6152 /* Check the instance and the mode parameters */
6153 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6154 assert_param(IS_I3C_MODE(hi3c->Mode));
6155
6156 it_source = READ_REG(hi3c->Instance->IER);
6157
6158 /* Get I3C handle state */
6159 handle_state = hi3c->State;
6160
6161 /* Check on user parameters */
6162 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U))
6163 {
6164 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6165 status = HAL_ERROR;
6166 }
6167 /* Check on hdmarx handle */
6168 else if (hi3c->hdmarx == NULL)
6169 {
6170 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
6171 status = HAL_ERROR;
6172
6173 /* Update handle state parameter */
6174 I3C_StateUpdate(hi3c);
6175 }
6176 /* check on the Mode */
6177 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6178 {
6179 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6180 status = HAL_ERROR;
6181 }
6182 /* check on the State */
6183 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6184 {
6185 status = HAL_BUSY;
6186 }
6187 /* check if DEF and GRP CCC notifications are enabled */
6188 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
6189 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
6190 {
6191 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6192 status = HAL_ERROR;
6193 }
6194 /* Verify the dynamic address validity */
6195 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6196 {
6197 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6198 status = HAL_ERROR;
6199 }
6200 else
6201 {
6202 /* Set handle transfer parameters */
6203 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6204 hi3c->State = HAL_I3C_STATE_BUSY_RX;
6205 hi3c->pXferData = pXferData;
6206 hi3c->RxXferCount = pXferData->RxBuf.Size;
6207 hi3c->XferISR = I3C_Tgt_Rx_DMA_ISR;
6208
6209 /*------------------------------------ I3C DMA channel for the Rx Data ---------------------------------------*/
6210 /* Set the I3C DMA transfer complete callback */
6211 hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt;
6212
6213 /* Set the DMA error callback */
6214 hi3c->hdmarx->XferErrorCallback = I3C_DMAError;
6215
6216 /* Set the unused DMA callbacks to NULL */
6217 hi3c->hdmarx->XferHalfCpltCallback = NULL;
6218 hi3c->hdmarx->XferAbortCallback = NULL;
6219
6220 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
6221 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
6222 {
6223 /* assert that DMA source and destination width are configured in byte */
6224 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
6225 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth));
6226
6227 /* Enable the Rx data DMA channel */
6228 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR,
6229 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size);
6230 }
6231 else
6232 {
6233 /* assert that DMA source and destination width are configured in word */
6234 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
6235 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth));
6236
6237 /* Check to align data size in words */
6238 if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U)
6239 {
6240 /* Keep the same size */
6241 size_align_word = hi3c->pXferData->RxBuf.Size;
6242 }
6243 else
6244 {
6245 /* Modify size to be multiple of 4 */
6246 size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U));
6247 }
6248
6249 /* Enable the Rx data DMA channel */
6250 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR,
6251 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word);
6252 }
6253
6254 if (rx_dma_status == HAL_OK)
6255 {
6256 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
6257 of I3C interrupt handle execution before current process unlock */
6258
6259 /* Enable Rx process interrupts */
6260 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
6261
6262 /* Update the number of remaining data bytes */
6263 hi3c->RxXferCount = 0U;
6264
6265 /* Enable Rx data DMA Request */
6266 LL_I3C_EnableDMAReq_RX(hi3c->Instance);
6267 }
6268 else
6269 {
6270 /* Set callback to NULL if DMA started */
6271 hi3c->hdmarx->XferCpltCallback = NULL;
6272 hi3c->hdmarx->XferErrorCallback = NULL;
6273
6274 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
6275 status = HAL_ERROR;
6276
6277 /* Update handle state parameter */
6278 I3C_StateUpdate(hi3c);
6279 }
6280 }
6281 }
6282
6283 return status;
6284 }
6285 #endif /* HAL_DMA_MODULE_ENABLED */
6286
6287 /**
6288 * @brief Target send control role request in polling mode.
6289 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6290 * for the specified I3C.
6291 * @param timeout : [IN] Timeout duration in millisecond.
6292 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6293 */
HAL_I3C_Tgt_ControlRoleReq(I3C_HandleTypeDef * hi3c,uint32_t timeout)6294 HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq(I3C_HandleTypeDef *hi3c, uint32_t timeout)
6295 {
6296 uint32_t tickstart;
6297 HAL_I3C_StateTypeDef handle_state;
6298 HAL_StatusTypeDef status = HAL_OK;
6299
6300 /* check on the handle */
6301 if (hi3c == NULL)
6302 {
6303 status = HAL_ERROR;
6304 }
6305 else
6306 {
6307 /* Check the instance and the mode parameters */
6308 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6309 assert_param(IS_I3C_MODE(hi3c->Mode));
6310
6311 /* Get I3C handle state */
6312 handle_state = hi3c->State;
6313
6314 /* check on the Mode */
6315 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6316 {
6317 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6318 status = HAL_ERROR;
6319 }
6320 /* check on the State */
6321 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6322 {
6323 status = HAL_BUSY;
6324 }
6325 /* Verify the dynamic address validity */
6326 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6327 {
6328 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6329 status = HAL_ERROR;
6330 }
6331 else
6332 {
6333 /* Verify if control role request feature is enabled */
6334 if (LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance) != 1U)
6335 {
6336 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6337 status = HAL_ERROR;
6338 }
6339 }
6340
6341 if (status == HAL_OK)
6342 {
6343 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6344 hi3c->State = HAL_I3C_STATE_BUSY;
6345
6346 /* Init tickstart for timeout management */
6347 tickstart = HAL_GetTick();
6348
6349 /* Request Controllership */
6350 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ, 0U);
6351
6352 /* Wait Controllership completion confirmation flag */
6353 status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_CRUPDF, RESET, timeout, tickstart);
6354
6355 /* Clear Control role request flag */
6356 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_CRUPDF) == SET)
6357 {
6358 LL_I3C_ClearFlag_CRUPD(hi3c->Instance);
6359 }
6360
6361 /* Check on error flag */
6362 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6363 {
6364 /* Clear error flag */
6365 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6366
6367 /* Update handle error code parameter */
6368 I3C_GetErrorSources(hi3c);
6369
6370 /* Update handle state parameter to previous state */
6371 I3C_StateUpdate(hi3c);
6372
6373 status = HAL_ERROR;
6374 }
6375 else
6376 {
6377 /* Update handle state parameter to previous state */
6378 I3C_StateUpdate(hi3c);
6379 }
6380 }
6381 }
6382
6383 return status;
6384 }
6385
6386 /**
6387 * @brief Target send control role request in interrupt mode.
6388 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6389 * for the specified I3C.
6390 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6391 */
HAL_I3C_Tgt_ControlRoleReq_IT(I3C_HandleTypeDef * hi3c)6392 HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq_IT(I3C_HandleTypeDef *hi3c)
6393 {
6394 HAL_I3C_StateTypeDef handle_state;
6395 HAL_StatusTypeDef status = HAL_OK;
6396
6397 /* check on the handle */
6398 if (hi3c == NULL)
6399 {
6400 status = HAL_ERROR;
6401 }
6402 else
6403 {
6404 /* Check the instance and the mode parameters */
6405 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6406 assert_param(IS_I3C_MODE(hi3c->Mode));
6407
6408 /* Get I3C handle state */
6409 handle_state = hi3c->State;
6410
6411 /* Check on the Mode */
6412 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6413 {
6414 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6415 status = HAL_ERROR;
6416 }
6417 /* check on the State */
6418 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6419 {
6420 status = HAL_BUSY;
6421 }
6422 /* Verify the dynamic address validity */
6423 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6424 {
6425 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6426 status = HAL_ERROR;
6427 }
6428 else
6429 {
6430 /* Verify if control role request feature is enabled */
6431 if (LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance) != 1U)
6432 {
6433 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6434 status = HAL_ERROR;
6435 }
6436 }
6437
6438 if (status == HAL_OK)
6439 {
6440 /* Update handle parameters */
6441 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6442 hi3c->State = HAL_I3C_STATE_BUSY;
6443 hi3c->XferISR = I3C_Tgt_CtrlRole_ISR;
6444
6445 /* Enable controller-role update and error interrupts */
6446 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_CTRLROLE);
6447
6448 /* Request Controllership */
6449 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ, 0U);
6450 }
6451 }
6452
6453 return status;
6454 }
6455
6456 /**
6457 * @brief Target send hot join request in polling mode.
6458 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6459 * information for the specified I3C.
6460 * @param pAddress : [IN/OUT] Pointer to the target own dynamic address assigned by the controller.
6461 * @param timeout : [IN] Timeout duration in millisecond.
6462 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6463 */
HAL_I3C_Tgt_HotJoinReq(I3C_HandleTypeDef * hi3c,uint8_t * pAddress,uint32_t timeout)6464 HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq(I3C_HandleTypeDef *hi3c, uint8_t *pAddress, uint32_t timeout)
6465 {
6466 uint32_t tickstart;
6467 HAL_I3C_StateTypeDef handle_state;
6468 uint32_t valid_dynamic_address;
6469 HAL_StatusTypeDef status = HAL_OK;
6470
6471 /* check on the handle */
6472 if (hi3c == NULL)
6473 {
6474 status = HAL_ERROR;
6475 }
6476 else
6477 {
6478 /* Check the instance and the mode parameters */
6479 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6480 assert_param(IS_I3C_MODE(hi3c->Mode));
6481
6482 /* Get I3C handle state */
6483 handle_state = hi3c->State;
6484
6485 /* Check on the pAddress value */
6486 if (pAddress == NULL)
6487 {
6488 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6489 status = HAL_ERROR;
6490 }
6491 /* Check on the Mode */
6492 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6493 {
6494 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6495 status = HAL_ERROR;
6496 }
6497 /* check on the State */
6498 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6499 {
6500 status = HAL_BUSY;
6501 }
6502 else
6503 {
6504 /* Check on the hot join request feature */
6505 if (LL_I3C_IsEnabledHotJoin(hi3c->Instance) != 1U)
6506 {
6507 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6508 status = HAL_ERROR;
6509 }
6510 }
6511
6512 if (status == HAL_OK)
6513 {
6514 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6515 hi3c->State = HAL_I3C_STATE_BUSY;
6516
6517 /* Init tickstart for timeout management */
6518 tickstart = HAL_GetTick();
6519
6520 /* Request hot join */
6521 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_HOT_JOIN, 0U);
6522
6523 /* Wait hot join completion confirmation flag */
6524 status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_DAUPDF, RESET, timeout, tickstart);
6525
6526 /* Clear dynamic address update flag */
6527 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_DAUPDF) == SET)
6528 {
6529 LL_I3C_ClearFlag_DAUPD(hi3c->Instance);
6530 }
6531
6532 /* Get dynamic address validity flag */
6533 valid_dynamic_address = LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance);
6534
6535 /* Check the validity of the own dynamic address */
6536 if (valid_dynamic_address == 0U)
6537 {
6538 hi3c->ErrorCode = HAL_I3C_ERROR_DYNAMIC_ADDR;
6539 status = HAL_ERROR;
6540
6541 /* Update handle state parameter to previous state */
6542 I3C_StateUpdate(hi3c);
6543 }
6544 /* Check on error flag */
6545 else if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6546 {
6547 /* Clear error flag */
6548 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6549
6550 /* Update handle error code parameter */
6551 I3C_GetErrorSources(hi3c);
6552
6553 /* Update handle state parameter to previous state */
6554 I3C_StateUpdate(hi3c);
6555
6556 status = HAL_ERROR;
6557 }
6558 else
6559 {
6560 /* Update handle state parameter to previous state */
6561 I3C_StateUpdate(hi3c);
6562
6563 /* Get assigned dynamic address */
6564 *pAddress = LL_I3C_GetOwnDynamicAddress(hi3c->Instance);
6565 }
6566 }
6567 }
6568
6569 return status;
6570 }
6571
6572 /**
6573 * @brief Target send hot join request in interrupt mode.
6574 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6575 * information for the specified I3C.
6576 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6577 */
HAL_I3C_Tgt_HotJoinReq_IT(I3C_HandleTypeDef * hi3c)6578 HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq_IT(I3C_HandleTypeDef *hi3c)
6579 {
6580 HAL_I3C_StateTypeDef handle_state;
6581 HAL_StatusTypeDef status = HAL_OK;
6582
6583 /* check on the handle */
6584 if (hi3c == NULL)
6585 {
6586 status = HAL_ERROR;
6587 }
6588 else
6589 {
6590 /* Check the instance and the mode parameters */
6591 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6592 assert_param(IS_I3C_MODE(hi3c->Mode));
6593
6594 /* Get I3C handle state */
6595 handle_state = hi3c->State;
6596
6597 /* Check on the Mode */
6598 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6599 {
6600 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6601 status = HAL_ERROR;
6602 }
6603 /* check on the State */
6604 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6605 {
6606 status = HAL_BUSY;
6607 }
6608 /* Check on the hot join request feature */
6609 else if (LL_I3C_IsEnabledHotJoin(hi3c->Instance) != 1U)
6610 {
6611 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6612 status = HAL_ERROR;
6613 }
6614 else
6615 {
6616 /* Update handle parameters */
6617 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6618 hi3c->State = HAL_I3C_STATE_BUSY;
6619 hi3c->XferISR = I3C_Tgt_HotJoin_ISR;
6620
6621 /* Enable dynamic address update and error interrupts */
6622 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_HOTJOIN);
6623
6624 /* Request hot join */
6625 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_HOT_JOIN, 0U);
6626 }
6627 }
6628
6629 return status;
6630 }
6631
6632 /**
6633 * @brief Target send IBI request in polling mode.
6634 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6635 * information for the specified I3C.
6636 * @param pPayload : [IN] Pointer to the buffer contains the payload data.
6637 * @param payloadSize : [IN] Payload buffer size in bytes.
6638 * @param timeout : [IN] Timeout duration in millisecond.
6639 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6640 */
HAL_I3C_Tgt_IBIReq(I3C_HandleTypeDef * hi3c,const uint8_t * pPayload,uint8_t payloadSize,uint32_t timeout)6641 HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload,
6642 uint8_t payloadSize, uint32_t timeout)
6643 {
6644 uint32_t tickstart;
6645 uint32_t payload_value = 0U;
6646 HAL_I3C_StateTypeDef handle_state;
6647 HAL_StatusTypeDef status = HAL_OK;
6648
6649 /* check on the handle */
6650 if (hi3c == NULL)
6651 {
6652 status = HAL_ERROR;
6653 }
6654 else
6655 {
6656 /* Check the instance and the mode parameters */
6657 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6658 assert_param(IS_I3C_MODE(hi3c->Mode));
6659
6660 /* Get I3C handle state */
6661 handle_state = hi3c->State;
6662
6663 /* Check on the Mode */
6664 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6665 {
6666 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6667 status = HAL_ERROR;
6668 }
6669 /* check on the State */
6670 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6671 {
6672 status = HAL_BUSY;
6673 }
6674 /* Verify the dynamic address validity */
6675 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6676 {
6677 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6678 status = HAL_ERROR;
6679 }
6680 else
6681 {
6682 /* Verify if IBI request feature is enabled*/
6683 if ((LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U))
6684 {
6685 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6686 status = HAL_ERROR;
6687 }
6688 }
6689
6690 if (status == HAL_OK)
6691 {
6692 /* Update handle parameters */
6693 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6694 hi3c->State = HAL_I3C_STATE_BUSY;
6695
6696 /* Check on the IBI additional data */
6697 if (LL_I3C_GetDeviceIBIPayload(hi3c->Instance) == LL_I3C_IBI_ADDITIONAL_DATA)
6698 {
6699 /* Check on the pPayload and payloadSize values */
6700 if ((pPayload == NULL) || (payloadSize == 0U))
6701 {
6702 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6703 status = HAL_ERROR;
6704
6705 /* Update handle state parameter */
6706 I3C_StateUpdate(hi3c);
6707 }
6708 else
6709 {
6710 /* For loop to calculate the payload value */
6711 for (uint32_t index = 0U; index < payloadSize; index++)
6712 {
6713 payload_value |= ((uint32_t)pPayload[index] << (index * 8U));
6714 }
6715
6716 /* Load IBI payload data */
6717 LL_I3C_SetIBIPayload(hi3c->Instance, payload_value);
6718 }
6719 }
6720
6721 if (status == HAL_OK)
6722 {
6723 /* Init tickstart for timeout management */
6724 tickstart = HAL_GetTick();
6725
6726 /* Request IBI */
6727 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_IBI, payloadSize);
6728
6729 /* Wait IBI completion confirmation flag */
6730 status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_IBIENDF, RESET, timeout, tickstart);
6731
6732 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_IBIENDF) == SET)
6733 {
6734 /* Clear IBI end process flag */
6735 LL_I3C_ClearFlag_IBIEND(hi3c->Instance);
6736 }
6737
6738 /* Check on error flag value */
6739 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6740 {
6741 /* Clear error flag */
6742 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6743
6744 /* Update handle error code parameter */
6745 I3C_GetErrorSources(hi3c);
6746
6747 /* Update handle state parameter to previous state */
6748 I3C_StateUpdate(hi3c);
6749
6750 status = HAL_ERROR;
6751 }
6752 else
6753 {
6754 /* Update handle state parameter to previous state */
6755 I3C_StateUpdate(hi3c);
6756 }
6757 }
6758 }
6759 }
6760
6761 return status;
6762 }
6763
6764 /**
6765 * @brief Target send IBI request in interrupt mode.
6766 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6767 * information for the specified I3C.
6768 * @param pPayload : [IN] Pointer to the buffer contains the payload data.
6769 * @param payloadSize : [IN] Payload buffer size in bytes.
6770 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6771 */
HAL_I3C_Tgt_IBIReq_IT(I3C_HandleTypeDef * hi3c,const uint8_t * pPayload,uint8_t payloadSize)6772 HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq_IT(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload, uint8_t payloadSize)
6773 {
6774 uint32_t payload_value = 0U;
6775 HAL_I3C_StateTypeDef handle_state;
6776 HAL_StatusTypeDef status = HAL_OK;
6777
6778 /* check on the handle */
6779 if (hi3c == NULL)
6780 {
6781 status = HAL_ERROR;
6782 }
6783 else
6784 {
6785 /* Check the instance and the mode parameters */
6786 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6787 assert_param(IS_I3C_MODE(hi3c->Mode));
6788
6789 /* Get I3C handle state */
6790 handle_state = hi3c->State;
6791
6792 /* Check on the Mode */
6793 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6794 {
6795 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6796 status = HAL_ERROR;
6797 }
6798 /* check on the State */
6799 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6800 {
6801 status = HAL_BUSY;
6802 }
6803 /* Verify the dynamic address validity */
6804 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6805 {
6806 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6807 status = HAL_ERROR;
6808 }
6809 else
6810 {
6811 /* Verify if IBI request feature is enabled */
6812 if (LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U)
6813 {
6814 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6815 status = HAL_ERROR;
6816 }
6817 }
6818
6819 if (status == HAL_OK)
6820 {
6821 /* Update handle parameters */
6822 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6823 hi3c->State = HAL_I3C_STATE_BUSY;
6824 hi3c->XferISR = I3C_Tgt_IBI_ISR;
6825
6826 /* Check on the IBI additional data */
6827 if (LL_I3C_GetDeviceIBIPayload(hi3c->Instance) == LL_I3C_IBI_ADDITIONAL_DATA)
6828 {
6829 /* Check on the pPayload and payloadSize values */
6830 if ((pPayload == NULL) || (payloadSize == 0U))
6831 {
6832 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6833 status = HAL_ERROR;
6834
6835 /* Update handle state parameter */
6836 I3C_StateUpdate(hi3c);
6837 }
6838 else
6839 {
6840 /* For loop to calculate the payload value */
6841 for (uint32_t index = 0U; index < payloadSize; index++)
6842 {
6843 payload_value |= ((uint32_t)pPayload[index] << (index * 8U));
6844 }
6845
6846 /* Load IBI payload data */
6847 LL_I3C_SetIBIPayload(hi3c->Instance, payload_value);
6848 }
6849 }
6850
6851 /* Enable IBI end and error interrupts */
6852 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_IBI);
6853
6854 /* Request IBI */
6855 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_IBI, payloadSize);
6856 }
6857 }
6858
6859 return status;
6860 }
6861 /**
6862 * @}
6863 */
6864
6865 /** @defgroup I3C_Exported_Functions_Group7 Generic and Common functions.
6866 * @brief I3C generic and common functions.
6867 *
6868 @verbatim
6869 =======================================================================================================================
6870 ##### Generic and Common functions #####
6871 =======================================================================================================================
6872 [..] This subsection provides a set of functions allowing to Abort transfer or to get in run-time the status
6873 of the peripheral.
6874
6875 (+) Call the function HAL_I3C_Abort_IT() to abort the current transfer either in DMA or IT.
6876 (+) Call the function HAL_I3C_GetState() to get the I3C handle state.
6877 (+) Call the function HAL_I3C_GetMode() to get the I3C handle mode.
6878 (+) Call the function HAL_I3C_GetError() to get the error code.
6879 (+) Call the function HAL_I3C_Get_ENTDAA_Payload_Info() to get BCR, DCR and PID information after ENTDAA.
6880
6881 @endverbatim
6882 * @{
6883 */
6884
6885 /**
6886 * @brief Abort an I3C IT or DMA process communication with Interrupt.
6887 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6888 * information for the specified I3C.
6889 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6890 */
HAL_I3C_Abort_IT(I3C_HandleTypeDef * hi3c)6891 HAL_StatusTypeDef HAL_I3C_Abort_IT(I3C_HandleTypeDef *hi3c)
6892 {
6893 HAL_StatusTypeDef status = HAL_OK;
6894
6895 /* check on the handle */
6896 if (hi3c == NULL)
6897 {
6898 status = HAL_ERROR;
6899 }
6900 else
6901 {
6902 if (hi3c->State != HAL_I3C_STATE_ABORT)
6903 {
6904 /* Set State at HAL_I3C_STATE_ABORT */
6905 hi3c->State = HAL_I3C_STATE_ABORT;
6906
6907 /* Disable Error Interrupts */
6908 __HAL_I3C_DISABLE_IT(hi3c, HAL_I3C_IT_ERRIE);
6909
6910 hi3c->XferISR = I3C_Abort_ISR;
6911
6912 /* Flush the different Fifos to generate an automatic stop mode link to underflow or overflow detection timeout */
6913 /* Flush the content of Tx Fifo */
6914 LL_I3C_RequestTxFIFOFlush(hi3c->Instance);
6915
6916 /* Flush the content of Rx Fifo */
6917 LL_I3C_RequestRxFIFOFlush(hi3c->Instance);
6918
6919 /* Check on the I3C mode: Control and status FIFOs available only with controller mode */
6920 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
6921 {
6922 /* Flush the content of Control Fifo */
6923 LL_I3C_RequestControlFIFOFlush(hi3c->Instance);
6924
6925 /* Flush the content of Status Fifo */
6926 LL_I3C_RequestStatusFIFOFlush(hi3c->Instance);
6927 }
6928
6929 /* Disable all DMA Requests */
6930 LL_I3C_DisableDMAReq_Control(hi3c->Instance);
6931 LL_I3C_DisableDMAReq_RX(hi3c->Instance);
6932 LL_I3C_DisableDMAReq_TX(hi3c->Instance);
6933 LL_I3C_DisableDMAReq_Status(hi3c->Instance);
6934
6935 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
6936 {
6937 /* Note : The I3C interrupts must be enabled after unlocking current process
6938 to avoid the risk of I3C interrupt handle execution before current
6939 process unlock */
6940 I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
6941 }
6942 else
6943 {
6944 /* Note : The I3C interrupts must be enabled after unlocking current process
6945 to avoid the risk of I3C interrupt handle execution before current
6946 process unlock */
6947 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT);
6948 }
6949 }
6950 else
6951 {
6952 return HAL_BUSY;
6953 }
6954 }
6955
6956 return status;
6957 }
6958
6959 /**
6960 * @brief Return the I3C handle state.
6961 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6962 * information for the specified I3C.
6963 * @retval HAL State : [OUT] Value from HAL_I3C_StateTypeDef enumeration.
6964 */
HAL_I3C_GetState(const I3C_HandleTypeDef * hi3c)6965 HAL_I3C_StateTypeDef HAL_I3C_GetState(const I3C_HandleTypeDef *hi3c)
6966 {
6967 return hi3c->State;
6968 }
6969
6970 /**
6971 * @brief Returns the I3C handle mode.
6972 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6973 * information for the specified I3C.
6974 * @retval HAL Mode : [OUT] Value from HAL_I3C_ModeTypeDef enumeration.
6975 */
HAL_I3C_GetMode(const I3C_HandleTypeDef * hi3c)6976 HAL_I3C_ModeTypeDef HAL_I3C_GetMode(const I3C_HandleTypeDef *hi3c)
6977 {
6978 return hi3c->Mode;
6979 }
6980
6981 /**
6982 * @brief Return the I3C error code.
6983 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6984 * information for the specified I3C.
6985 * @retval I3C Error Code : [OUT] Value from @ref I3C_ERROR_CODE_DEFINITION.
6986 */
HAL_I3C_GetError(const I3C_HandleTypeDef * hi3c)6987 uint32_t HAL_I3C_GetError(const I3C_HandleTypeDef *hi3c)
6988 {
6989 return hi3c->ErrorCode;
6990 }
6991
6992 /**
6993 * @brief Target/Controller Get Common Command Code Information updated after event.
6994 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6995 * for the specified I3C.
6996 * @param notifyId : [IN] Parameter indicates which notification is signaled.
6997 * It can be a combination of value of @ref HAL_I3C_Notification_ID_definition.
6998 * @param pCCCInfo : [IN/OUT] Pointer to an I3C_CCCInfoTypeDef structure that contains the CCC information
6999 * updated after CCC event.
7000 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7001 */
HAL_I3C_GetCCCInfo(I3C_HandleTypeDef * hi3c,uint32_t notifyId,I3C_CCCInfoTypeDef * pCCCInfo)7002 HAL_StatusTypeDef HAL_I3C_GetCCCInfo(I3C_HandleTypeDef *hi3c,
7003 uint32_t notifyId,
7004 I3C_CCCInfoTypeDef *pCCCInfo)
7005 {
7006 HAL_StatusTypeDef status = HAL_OK;
7007
7008 /* check on the handle */
7009 if (hi3c == NULL)
7010 {
7011 status = HAL_ERROR;
7012 }
7013 else
7014 {
7015 /* Check on user parameters */
7016 if (pCCCInfo == NULL)
7017 {
7018 /* Update handle error code parameter */
7019 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
7020 status = HAL_ERROR;
7021 }
7022 /* Check the I3C state */
7023 else if (hi3c->State == HAL_I3C_STATE_RESET)
7024 {
7025 /* Update handle error code parameter */
7026 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
7027 status = HAL_ERROR;
7028 }
7029 else
7030 {
7031 /* Retrieve Target Dynamic Address value and Validity (target/controller) */
7032 if ((notifyId & EVENT_ID_DAU) == EVENT_ID_DAU)
7033 {
7034 pCCCInfo->DynamicAddrValid = LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance);
7035 pCCCInfo->DynamicAddr = LL_I3C_GetOwnDynamicAddress(hi3c->Instance);
7036 }
7037
7038 /* Retrieve Maximum Write Data Length (target) */
7039 if ((notifyId & EVENT_ID_SETMWL) == EVENT_ID_SETMWL)
7040 {
7041 pCCCInfo->MaxWriteLength = LL_I3C_GetMaxWriteLength(hi3c->Instance);
7042 }
7043
7044 /* Retrieve Maximum Read Data Length (target) */
7045 if ((notifyId & EVENT_ID_SETMRL) == EVENT_ID_SETMRL)
7046 {
7047 pCCCInfo->MaxReadLength = LL_I3C_GetMaxReadLength(hi3c->Instance);
7048 }
7049
7050 /* Retrieve Reset Action/Level on received reset pattern (target) */
7051 if ((notifyId & EVENT_ID_RSTACT) == EVENT_ID_RSTACT)
7052 {
7053 pCCCInfo->ResetAction = LL_I3C_GetResetAction(hi3c->Instance);
7054 }
7055
7056 /* Retrieve Activity State (target) */
7057 if ((notifyId & EVENT_ID_ENTASx) == EVENT_ID_ENTASx)
7058 {
7059 pCCCInfo->ActivityState = LL_I3C_GetActivityState(hi3c->Instance);
7060 }
7061
7062 /* Retrieve Interrupt allowed status (target) */
7063 if ((notifyId & EVENT_ID_ENEC_DISEC) == EVENT_ID_ENEC_DISEC)
7064 {
7065 pCCCInfo->HotJoinAllowed = LL_I3C_IsEnabledHotJoin(hi3c->Instance);
7066 pCCCInfo->InBandAllowed = LL_I3C_IsEnabledIBI(hi3c->Instance);
7067 pCCCInfo->CtrlRoleAllowed = LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance);
7068 }
7069
7070 /* Retrieve In Band Interrupt information (controller) */
7071 if ((notifyId & EVENT_ID_IBI) == EVENT_ID_IBI)
7072 {
7073 pCCCInfo->IBICRTgtAddr = LL_I3C_GetIBITargetAddr(hi3c->Instance);
7074 pCCCInfo->IBITgtNbPayload = LL_I3C_GetNbIBIAddData(hi3c->Instance);
7075 pCCCInfo->IBITgtPayload = LL_I3C_GetIBIPayload(hi3c->Instance);
7076 }
7077
7078 /* Retrieve Controller role request Interrupt information (controller) */
7079 if ((notifyId & EVENT_ID_CR) == EVENT_ID_CR)
7080 {
7081 pCCCInfo->IBICRTgtAddr = LL_I3C_GetIBITargetAddr(hi3c->Instance);
7082 }
7083 }
7084 }
7085
7086 return status;
7087 }
7088
7089 /**
7090 * @brief Get BCR, DCR and PID information after ENTDAA.
7091 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7092 * for the specified I3C.
7093 * @param ENTDAA_payload :[IN] Payload received after ENTDAA
7094 * @param pENTDAA_payload :[OUT] Pointer to an I3C_ENTDAAPayloadTypeDef structure that contains the BCR, DCR and PID
7095 * information.
7096 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7097 */
HAL_I3C_Get_ENTDAA_Payload_Info(I3C_HandleTypeDef * hi3c,uint64_t ENTDAA_payload,I3C_ENTDAAPayloadTypeDef * pENTDAA_payload)7098 HAL_StatusTypeDef HAL_I3C_Get_ENTDAA_Payload_Info(I3C_HandleTypeDef *hi3c,
7099 uint64_t ENTDAA_payload,
7100 I3C_ENTDAAPayloadTypeDef *pENTDAA_payload)
7101 {
7102 HAL_StatusTypeDef status = HAL_OK;
7103 uint32_t BCR;
7104 uint64_t PID;
7105
7106 /* check on the handle */
7107 if (hi3c == NULL)
7108 {
7109 status = HAL_ERROR;
7110 }
7111 else
7112 {
7113 /* Check on user parameters */
7114 if (pENTDAA_payload == NULL)
7115 {
7116 /* Update handle error code parameter */
7117 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
7118 status = HAL_ERROR;
7119 }
7120 else
7121 {
7122 /* Get Bus Characterics */
7123 BCR = __HAL_I3C_GET_BCR(ENTDAA_payload);
7124
7125 /* Retrieve BCR information */
7126 pENTDAA_payload->BCR.IBIPayload = __HAL_I3C_GET_IBI_PAYLOAD(BCR);
7127 pENTDAA_payload->BCR.IBIRequestCapable = __HAL_I3C_GET_IBI_CAPABLE(BCR);
7128 pENTDAA_payload->BCR.DeviceRole = __HAL_I3C_GET_CR_CAPABLE(BCR);
7129 pENTDAA_payload->BCR.AdvancedCapabilities = I3C_GET_ADVANCED_CAPABLE(BCR);
7130 pENTDAA_payload->BCR.OfflineCapable = I3C_GET_OFFLINE_CAPABLE(BCR);
7131 pENTDAA_payload->BCR.VirtualTargetSupport = I3C_GET_VIRTUAL_TGT(BCR);
7132 pENTDAA_payload->BCR.MaxDataSpeedLimitation = I3C_GET_MAX_DATA_SPEED_LIMIT(BCR);
7133
7134 /* Get Device Characterics */
7135 pENTDAA_payload->DCR = I3C_GET_DCR(ENTDAA_payload);
7136
7137 /* Get Provisioned ID */
7138 PID = I3C_GET_PID(ENTDAA_payload);
7139
7140 /* Change PID from BigEndian to litlleEndian */
7141 PID = (uint64_t)((((uint64_t)I3C_BIG_TO_LITTLE_ENDIAN((uint32_t) PID) << 32) |
7142 ((uint64_t)I3C_BIG_TO_LITTLE_ENDIAN((uint32_t)(PID >> 32)))) >> 16);
7143
7144 /* Retrieve PID information*/
7145 pENTDAA_payload->PID.MIPIMID = I3C_GET_MIPIMID(PID);
7146 pENTDAA_payload->PID.IDTSEL = I3C_GET_IDTSEL(PID);
7147 pENTDAA_payload->PID.PartID = I3C_GET_PART_ID(PID);
7148 pENTDAA_payload->PID.MIPIID = I3C_GET_MIPIID(PID);
7149 }
7150 }
7151
7152 return status;
7153 }
7154
7155 /**
7156 * @}
7157 */
7158
7159 /**
7160 * @}
7161 */
7162
7163 /* Private functions -------------------------------------------------------------------------------------------------*/
7164 /** @defgroup I3C_Private_Functions I3C Private Functions
7165 * @{
7166 */
7167
7168 /**
7169 * @brief Interrupt Sub-Routine which handles target received events.
7170 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7171 * for the specified I3C.
7172 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7173 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7174 */
I3C_Tgt_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7175 static HAL_StatusTypeDef I3C_Tgt_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7176 {
7177 uint32_t tmpevent = 0U;
7178
7179 /* I3C Rx FIFO not empty interrupt Check */
7180 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7181 {
7182 /* Call receive treatment function */
7183 hi3c->ptrRxFunc(hi3c);
7184 }
7185
7186 /* I3C target complete controller-role hand-off procedure (direct GETACCR CCC) event management --------------------*/
7187 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRUPDF) != RESET)
7188 {
7189 /* Clear controller-role update flag */
7190 LL_I3C_ClearFlag_CRUPD(hi3c->Instance);
7191
7192 /* Set Identifier EVENT_ID_GETACCCR */
7193 tmpevent |= EVENT_ID_GETACCCR;
7194 }
7195
7196 /* I3C target receive any direct GETxxx CCC event management -------------------------------------------------------*/
7197 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_GETF) != RESET)
7198 {
7199 /* Clear GETxxx CCC flag */
7200 LL_I3C_ClearFlag_GET(hi3c->Instance);
7201
7202 /* Set Identifier EVENT_ID_GETx */
7203 tmpevent |= EVENT_ID_GETx;
7204 }
7205
7206 /* I3C target receive get status command (direct GETSTATUS CCC) event management -----------------------------------*/
7207 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_STAF) != RESET)
7208 {
7209 /* Clear GETSTATUS CCC flag */
7210 LL_I3C_ClearFlag_STA(hi3c->Instance);
7211
7212 /* Set Identifier EVENT_ID_GETSTATUS */
7213 tmpevent |= EVENT_ID_GETSTATUS;
7214 }
7215
7216 /* I3C target receive a dynamic address update (ENTDAA/RSTDAA/SETNEWDA CCC) event management -----------------------*/
7217 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_DAUPDF) != RESET)
7218 {
7219 /* Clear dynamic address update flag */
7220 LL_I3C_ClearFlag_DAUPD(hi3c->Instance);
7221
7222 /* Set Identifier EVENT_ID_DAU */
7223 tmpevent |= EVENT_ID_DAU;
7224 }
7225
7226 /* I3C target receive maximum write length update (direct SETMWL CCC) event management -----------------------------*/
7227 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_MWLUPDF) != RESET)
7228 {
7229 /* Clear SETMWL CCC flag */
7230 LL_I3C_ClearFlag_MWLUPD(hi3c->Instance);
7231
7232 /* Set Identifier EVENT_ID_SETMWL */
7233 tmpevent |= EVENT_ID_SETMWL;
7234 }
7235
7236 /* I3C target receive maximum read length update(direct SETMRL CCC) event management -------------------------------*/
7237 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_MRLUPDF) != RESET)
7238 {
7239 /* Clear SETMRL CCC flag */
7240 LL_I3C_ClearFlag_MRLUPD(hi3c->Instance);
7241
7242 /* Set Identifier EVENT_ID_SETMRL */
7243 tmpevent |= EVENT_ID_SETMRL;
7244 }
7245
7246 /* I3C target detect reset pattern (broadcast or direct RSTACT CCC) event management -------------------------------*/
7247 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_RSTF) != RESET)
7248 {
7249 /* Clear reset pattern flag */
7250 LL_I3C_ClearFlag_RST(hi3c->Instance);
7251
7252 /* Set Identifier EVENT_ID_RSTACT */
7253 tmpevent |= EVENT_ID_RSTACT;
7254 }
7255
7256 /* I3C target receive activity state update (direct or broadcast ENTASx) CCC event management ----------------------*/
7257 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_ASUPDF) != RESET)
7258 {
7259 /* Clear ENTASx CCC flag */
7260 LL_I3C_ClearFlag_ASUPD(hi3c->Instance);
7261
7262 /* Set Identifier EVENT_ID_ENTASx */
7263 tmpevent |= EVENT_ID_ENTASx;
7264 }
7265
7266 /* I3C target receive a direct or broadcast ENEC/DISEC CCC event management ----------------------------------------*/
7267 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_INTUPDF) != RESET)
7268 {
7269 /* Clear ENEC/DISEC CCC flag */
7270 LL_I3C_ClearFlag_INTUPD(hi3c->Instance);
7271
7272 /* Set Identifier EVENT_ID_ENEC_DISEC */
7273 tmpevent |= EVENT_ID_ENEC_DISEC;
7274 }
7275
7276 /* I3C target receive a broadcast DEFTGTS CCC event management -----------------------------------------------------*/
7277 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_DEFF) != RESET)
7278 {
7279 /* Clear DEFTGTS CCC flag */
7280 LL_I3C_ClearFlag_DEF(hi3c->Instance);
7281
7282 /* Set Identifier EVENT_ID_DEFTGTS */
7283 tmpevent |= EVENT_ID_DEFTGTS;
7284 }
7285
7286 /* I3C target receive a group addressing (broadcast DEFGRPA CCC) event management ----------------------------------*/
7287 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_GRPF) != RESET)
7288 {
7289 /* Clear DEFGRPA CCC flag */
7290 LL_I3C_ClearFlag_GRP(hi3c->Instance);
7291
7292 /* Set Identifier EVENT_ID_DEFGRPA */
7293 tmpevent |= EVENT_ID_DEFGRPA;
7294 }
7295
7296 /* I3C target wakeup event management ----------------------------------*/
7297 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7298 {
7299 /* Clear WKP flag */
7300 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7301
7302 /* Set Identifier EVENT_ID_WKP */
7303 tmpevent |= EVENT_ID_WKP;
7304 }
7305
7306 if (tmpevent != 0U)
7307 {
7308 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7309 /* Call registered callback */
7310 hi3c->NotifyCallback(hi3c, tmpevent);
7311 #else
7312 /* Asynchronous receive CCC event Callback */
7313 HAL_I3C_NotifyCallback(hi3c, tmpevent);
7314 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7315 }
7316
7317 /* Update handle state parameter */
7318 I3C_StateUpdate(hi3c);
7319
7320 return HAL_OK;
7321 }
7322
7323 /**
7324 * @brief Interrupt Sub-Routine which handles Controller received events.
7325 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7326 * for the specified I3C.
7327 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7328 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7329 */
I3C_Ctrl_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7330 static HAL_StatusTypeDef I3C_Ctrl_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7331 {
7332 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
7333 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
7334 {
7335 /* Clear IBI request flag */
7336 LL_I3C_ClearFlag_IBI(hi3c->Instance);
7337
7338 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7339 /* Call registered callback */
7340 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
7341 #else
7342 /* Asynchronous IBI event Callback */
7343 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
7344 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7345 }
7346
7347 /* I3C controller controller-role request event management ---------------------------------------------------------*/
7348 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
7349 {
7350 /* Clear controller-role request flag */
7351 LL_I3C_ClearFlag_CR(hi3c->Instance);
7352
7353 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7354 /* Call registered callback */
7355 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
7356 #else
7357 /* Asynchronous controller-role event Callback */
7358 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
7359 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7360 }
7361
7362 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
7363 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
7364 {
7365 /* Clear hot-join flag */
7366 LL_I3C_ClearFlag_HJ(hi3c->Instance);
7367
7368 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7369 /* Call registered callback */
7370 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
7371 #else
7372 /* Asynchronous hot-join event Callback */
7373 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
7374 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7375 }
7376
7377 /* Update handle state parameter */
7378 I3C_StateUpdate(hi3c);
7379
7380 return HAL_OK;
7381 }
7382
7383 /**
7384 * @brief Interrupt Sub-Routine which handles target hot join event.
7385 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7386 * for the specified I3C.
7387 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7388 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7389 */
I3C_Tgt_HotJoin_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7390 static HAL_StatusTypeDef I3C_Tgt_HotJoin_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7391 {
7392 /* I3C target receive a dynamic address update event management */
7393 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_DAUPDF) != RESET)
7394 {
7395 /* Clear dynamic address update flag */
7396 LL_I3C_ClearFlag_DAUPD(hi3c->Instance);
7397
7398 /* Disable dynamic address update and error interrupts */
7399 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_HOTJOIN);
7400
7401 /* Check the validity of the own dynamic address */
7402 if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) == 1U)
7403 {
7404 /* Update handle state parameter */
7405 I3C_StateUpdate(hi3c);
7406
7407 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7408
7409 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7410 /* Call registered callback */
7411 hi3c->TgtHotJoinCallback(hi3c, (uint8_t)LL_I3C_GetOwnDynamicAddress(hi3c->Instance));
7412 #else
7413 /* Asynchronous receive ENTDAA/RSTDAA/SETNEWDA CCC event Callback */
7414 HAL_I3C_TgtHotJoinCallback(hi3c, (uint8_t)LL_I3C_GetOwnDynamicAddress(hi3c->Instance));
7415 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7416 }
7417 else
7418 {
7419 hi3c->ErrorCode = HAL_I3C_ERROR_DYNAMIC_ADDR;
7420
7421 /* Call error treatment function */
7422 I3C_ErrorTreatment(hi3c);
7423 }
7424 }
7425 return HAL_OK;
7426 }
7427
7428 /**
7429 * @brief Interrupt Sub-Routine which handles target control role event.
7430 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7431 * for the specified I3C.
7432 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7433 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7434 */
I3C_Tgt_CtrlRole_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7435 static HAL_StatusTypeDef I3C_Tgt_CtrlRole_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7436 {
7437 /* I3C target complete controller-role hand-off procedure (direct GETACCR CCC) event management -------------------*/
7438 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRUPDF) != RESET)
7439 {
7440 /* Clear controller-role update flag */
7441 LL_I3C_ClearFlag_CRUPD(hi3c->Instance);
7442
7443 /* Disable controller-role update and error interrupts */
7444 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_CTRLROLE);
7445
7446 /* Update handle state parameter */
7447 I3C_StateUpdate(hi3c);
7448
7449 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7450
7451 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7452 /* Call registered callback */
7453 hi3c->NotifyCallback(hi3c, EVENT_ID_GETACCCR);
7454 #else
7455 /* Asynchronous receive GETACCR CCC event Callback */
7456 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_GETACCCR);
7457 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7458 }
7459 return HAL_OK;
7460 }
7461
7462 /**
7463 * @brief Interrupt Sub-Routine which handles target IBI event.
7464 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7465 * for the specified I3C.
7466 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7467 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7468 */
I3C_Tgt_IBI_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7469 static HAL_StatusTypeDef I3C_Tgt_IBI_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7470 {
7471 /* I3C target IBI end process event management ---------------------------------------------------------------------*/
7472 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIENDF) != RESET)
7473 {
7474 /* Clear IBI end flag */
7475 LL_I3C_ClearFlag_IBIEND(hi3c->Instance);
7476
7477 /* Disable IBI end and error interrupts */
7478 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_IBI);
7479
7480 /* Update handle state parameter */
7481 I3C_StateUpdate(hi3c);
7482
7483 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7484
7485 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7486 /* Call registered callback */
7487 hi3c->NotifyCallback(hi3c, EVENT_ID_IBIEND);
7488 #else
7489 /* Asynchronous IBI end event Callback */
7490 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBIEND);
7491 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7492 }
7493 return HAL_OK;
7494 }
7495
7496 /**
7497 * @brief Interrupt Sub-Routine which handles target transmit data in Interrupt mode.
7498 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7499 * for the specified I3C.
7500 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7501 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7502 */
I3C_Tgt_Tx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7503 static HAL_StatusTypeDef I3C_Tgt_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7504 {
7505 /* Check that a Tx process is ongoing */
7506 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
7507 {
7508 /* I3C Tx FIFO not full interrupt Check */
7509 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7510 {
7511 if (hi3c->TxXferCount > 0U)
7512 {
7513 /* Call transmit treatment function */
7514 hi3c->ptrTxFunc(hi3c);
7515 }
7516 }
7517
7518 /* I3C target frame complete event Check */
7519 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7520 {
7521 /* Clear frame complete flag */
7522 LL_I3C_ClearFlag_FC(hi3c->Instance);
7523
7524 /* Check if all data bytes are transmitted */
7525 if (LL_I3C_GetXferDataCount(hi3c->Instance) == hi3c->pXferData->TxBuf.Size)
7526 {
7527 /* Disable Tx process interrupts */
7528 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_TX_IT);
7529
7530 /* Update handle state parameter */
7531 I3C_StateUpdate(hi3c);
7532
7533 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7534
7535 /* Call the transmit complete callback to inform upper layer of End of Transfer */
7536 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7537 hi3c->TgtTxCpltCallback(hi3c);
7538 #else
7539 HAL_I3C_TgtTxCpltCallback(hi3c);
7540 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7541 }
7542 else
7543 {
7544 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7545
7546 /* Call error treatment function */
7547 I3C_ErrorTreatment(hi3c);
7548 }
7549 }
7550
7551 /* I3C target wakeup event management ----------------------------------*/
7552 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7553 {
7554 /* Clear WKP flag */
7555 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7556
7557 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7558 /* Call registered callback */
7559 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7560 #else
7561 /* Asynchronous receive CCC event Callback */
7562 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7563 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7564 }
7565 }
7566
7567 return HAL_OK;
7568 }
7569
7570 /**
7571 * @brief Interrupt Sub-Routine which handles target receive data in Interrupt mode.
7572 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7573 * for the specified I3C.
7574 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7575 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7576 */
I3C_Tgt_Rx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7577 static HAL_StatusTypeDef I3C_Tgt_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7578 {
7579 /* Check that an Rx process is ongoing */
7580 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
7581 {
7582 /* I3C Rx FIFO not empty interrupt Check */
7583 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7584 {
7585 if (hi3c->RxXferCount > 0U)
7586 {
7587 /* Call receive treatment function */
7588 hi3c->ptrRxFunc(hi3c);
7589 }
7590 }
7591
7592 /* I3C target frame complete event Check */
7593 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7594 {
7595 /* Clear frame complete flag */
7596 LL_I3C_ClearFlag_FC(hi3c->Instance);
7597
7598 /* Check if all data bytes are received */
7599 if (LL_I3C_GetXferDataCount(hi3c->Instance) == hi3c->pXferData->RxBuf.Size)
7600 {
7601 /* Disable Rx process interrupts */
7602 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT);
7603
7604 /* Update handle state parameter */
7605 I3C_StateUpdate(hi3c);
7606
7607 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7608
7609 /* Call the receive complete callback to inform upper layer of End of Transfer */
7610 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7611 hi3c->TgtRxCpltCallback(hi3c);
7612 #else
7613 HAL_I3C_TgtRxCpltCallback(hi3c);
7614 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7615 }
7616 else
7617 {
7618 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7619
7620 /* Call error treatment function */
7621 I3C_ErrorTreatment(hi3c);
7622 }
7623 }
7624
7625 /* I3C target wakeup event management ----------------------------------*/
7626 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7627 {
7628 /* Clear WKP flag */
7629 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7630
7631 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7632 /* Call registered callback */
7633 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7634 #else
7635 /* Asynchronous receive CCC event Callback */
7636 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7637 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7638 }
7639 }
7640
7641 return HAL_OK;
7642 }
7643
7644 #if defined(HAL_DMA_MODULE_ENABLED)
7645 /**
7646 * @brief Interrupt Sub-Routine which handles target transmit data in DMA mode.
7647 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7648 * for the specified I3C.
7649 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7650 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7651 */
I3C_Tgt_Tx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7652 static HAL_StatusTypeDef I3C_Tgt_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7653 {
7654 /* Check that a Tx process is ongoing */
7655 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
7656 {
7657 /* I3C target frame complete event Check */
7658 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7659 {
7660 /* Clear frame complete flag */
7661 LL_I3C_ClearFlag_FC(hi3c->Instance);
7662
7663 /* Check if all data bytes are transmitted */
7664 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U)
7665 {
7666 /* Disable Tx process interrupts */
7667 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
7668
7669 /* Update handle state parameter */
7670 I3C_StateUpdate(hi3c);
7671
7672 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7673
7674 /* Update the number of remaining data bytes */
7675 hi3c->TxXferCount = 0U;
7676
7677 /* Call target transmit complete callback to inform upper layer of End of Transfer */
7678 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7679 hi3c->TgtTxCpltCallback(hi3c);
7680 #else
7681 HAL_I3C_TgtTxCpltCallback(hi3c);
7682 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7683 }
7684 else
7685 {
7686 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7687
7688 /* Call error treatment function */
7689 I3C_ErrorTreatment(hi3c);
7690 }
7691 }
7692
7693 /* I3C target wakeup event management ----------------------------------*/
7694 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7695 {
7696 /* Clear WKP flag */
7697 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7698
7699 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7700 /* Call registered callback */
7701 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7702 #else
7703 /* Asynchronous receive CCC event Callback */
7704 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7705 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7706 }
7707 }
7708
7709 return HAL_OK;
7710 }
7711
7712 /**
7713 * @brief Interrupt Sub-Routine which handles target receive data in DMA mode.
7714 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7715 * for the specified I3C.
7716 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7717 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7718 */
I3C_Tgt_Rx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7719 static HAL_StatusTypeDef I3C_Tgt_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7720 {
7721 /* Check that a Rx process is ongoing */
7722 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
7723 {
7724 /* I3C target frame complete event Check */
7725 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7726 {
7727 /* Clear frame complete flag */
7728 LL_I3C_ClearFlag_FC(hi3c->Instance);
7729
7730 /* Check if all data bytes are received */
7731 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U)
7732 {
7733 /* Disable Rx process interrupts */
7734 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
7735
7736 /* Update handle state parameter */
7737 I3C_StateUpdate(hi3c);
7738
7739 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7740
7741 /* Update the number of remaining data bytes */
7742 hi3c->RxXferCount = 0U;
7743
7744 /* Call target receive complete callback to inform upper layer of End of Transfer */
7745 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7746 hi3c->TgtRxCpltCallback(hi3c);
7747 #else
7748 HAL_I3C_TgtRxCpltCallback(hi3c);
7749 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7750 }
7751 else
7752 {
7753 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7754
7755 /* Call error treatment function */
7756 I3C_ErrorTreatment(hi3c);
7757 }
7758 }
7759
7760 /* I3C target wakeup event management ----------------------------------*/
7761 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7762 {
7763 /* Clear WKP flag */
7764 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7765
7766 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7767 /* Call registered callback */
7768 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7769 #else
7770 /* Asynchronous receive CCC event Callback */
7771 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7772 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7773 }
7774 }
7775
7776 return HAL_OK;
7777 }
7778 #endif /* HAL_DMA_MODULE_ENABLED */
7779
7780 /**
7781 * @brief Interrupt Sub-Routine which handles controller transmission in interrupt mode.
7782 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7783 * for the specified I3C.
7784 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7785 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7786 */
I3C_Ctrl_Tx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7787 static HAL_StatusTypeDef I3C_Ctrl_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7788 {
7789 /* Check that a Tx process is ongoing */
7790 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
7791 {
7792 /* Check if Control FIFO requests data */
7793 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
7794 {
7795 if (hi3c->ControlXferCount > 0U)
7796 {
7797 /* Call control data treatment function */
7798 I3C_ControlDataTreatment(hi3c);
7799 }
7800 }
7801
7802 /* I3C Tx FIFO not full interrupt Check */
7803 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7804 {
7805 if (hi3c->TxXferCount > 0U)
7806 {
7807 /* Call Transmit treatment function */
7808 hi3c->ptrTxFunc(hi3c);
7809 }
7810 }
7811
7812 /* I3C target frame complete event Check */
7813 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7814 {
7815 /* Clear frame complete flag */
7816 LL_I3C_ClearFlag_FC(hi3c->Instance);
7817
7818 if (hi3c->ControlXferCount == 0U)
7819 {
7820 /* Disable Tx process interrupts */
7821 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT);
7822
7823 /* Update handle state parameter */
7824 I3C_StateUpdate(hi3c);
7825
7826 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7827
7828 /* Call the transmit complete callback to inform upper layer of End of Transfer */
7829 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7830 hi3c->CtrlTxCpltCallback(hi3c);
7831 #else
7832 HAL_I3C_CtrlTxCpltCallback(hi3c);
7833 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7834 }
7835 else
7836 {
7837 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7838
7839 /* Call the transmit complete callback */
7840 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7841 hi3c->CtrlTxCpltCallback(hi3c);
7842 #else
7843 HAL_I3C_CtrlTxCpltCallback(hi3c);
7844 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7845
7846 /* Then Initiate a Start condition */
7847 LL_I3C_RequestTransfer(hi3c->Instance);
7848
7849 }
7850 }
7851 }
7852 return HAL_OK;
7853 }
7854
7855 /**
7856 * @brief Interrupt Sub-Routine which handles controller reception in interrupt mode.
7857 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7858 * for the specified I3C.
7859 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7860 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7861 */
I3C_Ctrl_Rx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7862 static HAL_StatusTypeDef I3C_Ctrl_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7863 {
7864 /* Check that an Rx process is ongoing */
7865 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
7866 {
7867 /* Check if Control FIFO requests data */
7868 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
7869 {
7870 if (hi3c->ControlXferCount > 0U)
7871 {
7872 /* Call control data treatment function */
7873 I3C_ControlDataTreatment(hi3c);
7874 }
7875 }
7876
7877 /* I3C Rx FIFO not empty interrupt Check */
7878 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7879 {
7880 if (hi3c->RxXferCount > 0U)
7881 {
7882 /* Call receive treatment function */
7883 hi3c->ptrRxFunc(hi3c);
7884 }
7885 }
7886
7887 /* I3C Tx FIFO not full interrupt Check */
7888 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7889 {
7890 if (hi3c->TxXferCount > 0U)
7891 {
7892 /* Call Transmit treatment function */
7893 hi3c->ptrTxFunc(hi3c);
7894 }
7895 }
7896
7897 /* I3C target frame complete event Check */
7898 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7899 {
7900 /* Clear frame complete flag */
7901 LL_I3C_ClearFlag_FC(hi3c->Instance);
7902
7903 if (hi3c->ControlXferCount == 0U)
7904 {
7905 /* Disable Rx process interrupts */
7906 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
7907
7908 /* Update handle state parameter */
7909 I3C_StateUpdate(hi3c);
7910
7911 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7912
7913 /* Call the receive complete callback */
7914 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7915 hi3c->CtrlRxCpltCallback(hi3c);
7916 #else
7917 HAL_I3C_CtrlRxCpltCallback(hi3c);
7918 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7919 }
7920 else
7921 {
7922 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7923
7924 /* Call the receive complete callback */
7925 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7926 hi3c->CtrlRxCpltCallback(hi3c);
7927 #else
7928 HAL_I3C_CtrlRxCpltCallback(hi3c);
7929 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7930
7931 /* Then Initiate a Start condition */
7932 LL_I3C_RequestTransfer(hi3c->Instance);
7933 }
7934 }
7935 }
7936 return HAL_OK;
7937 }
7938
7939 /**
7940 * @brief Interrupt Sub-Routine which handles controller multiple transmission/reception in interrupt mode.
7941 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7942 * for the specified I3C.
7943 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7944 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7945 */
I3C_Ctrl_Multiple_Xfer_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7946 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7947 {
7948 /* Check that a Tx/Rx process is ongoing */
7949 if (hi3c->State == HAL_I3C_STATE_BUSY_TX_RX)
7950 {
7951 /* Check if Control FIFO requests data */
7952 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
7953 {
7954 if (hi3c->ControlXferCount > 0U)
7955 {
7956 /* Call control data treatment function */
7957 I3C_ControlDataTreatment(hi3c);
7958 }
7959 }
7960
7961 /* I3C Tx FIFO not full interrupt Check */
7962 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7963 {
7964 if (hi3c->TxXferCount > 0U)
7965 {
7966 /* Call Transmit treatment function */
7967 hi3c->ptrTxFunc(hi3c);
7968 }
7969 }
7970
7971 /* I3C Rx FIFO not empty interrupt Check */
7972 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7973 {
7974 if (hi3c->RxXferCount > 0U)
7975 {
7976 /* Call receive treatment function */
7977 hi3c->ptrRxFunc(hi3c);
7978 }
7979 }
7980
7981 /* I3C target frame complete event Check */
7982 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7983 {
7984 /* Clear frame complete flag */
7985 LL_I3C_ClearFlag_FC(hi3c->Instance);
7986
7987 if (hi3c->ControlXferCount == 0U)
7988 {
7989 /* Disable Tx process interrupts */
7990 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT);
7991
7992 /* Disable Rx process interrupts */
7993 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
7994
7995 /* Update handle state parameter */
7996 I3C_StateUpdate(hi3c);
7997
7998 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7999
8000 /* Call the transmit, receive complete callback to inform upper layer of End of Transfer */
8001 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8002 hi3c->CtrlMultipleXferCpltCallback(hi3c);
8003 #else
8004 HAL_I3C_CtrlMultipleXferCpltCallback(hi3c);
8005 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8006 }
8007 else
8008 {
8009 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8010
8011 /* Then Initiate a Start condition */
8012 LL_I3C_RequestTransfer(hi3c->Instance);
8013 }
8014 }
8015 }
8016 return HAL_OK;
8017 }
8018
8019 /**
8020 * @brief Interrupt Sub-Routine which handles controller transmission and Controller received events
8021 * in interrupt mode.
8022 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8023 * for the specified I3C.
8024 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8025 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8026 */
I3C_Ctrl_Tx_Listen_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8027 static HAL_StatusTypeDef I3C_Ctrl_Tx_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8028 {
8029 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
8030 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
8031 {
8032 /* Clear IBI request flag */
8033 LL_I3C_ClearFlag_IBI(hi3c->Instance);
8034
8035 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8036 /* Call registered callback */
8037 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
8038 #else
8039 /* Asynchronous IBI event Callback */
8040 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
8041 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8042 }
8043
8044 /* I3C controller controller-role request event management ---------------------------------------------------------*/
8045 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
8046 {
8047 /* Clear controller-role request flag */
8048 LL_I3C_ClearFlag_CR(hi3c->Instance);
8049
8050 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8051 /* Call registered callback */
8052 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
8053 #else
8054 /* Asynchronous controller-role event Callback */
8055 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
8056 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8057 }
8058
8059 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
8060 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
8061 {
8062 /* Clear hot-join flag */
8063 LL_I3C_ClearFlag_HJ(hi3c->Instance);
8064
8065 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8066 /* Call registered callback */
8067 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
8068 #else
8069 /* Asynchronous hot-join event Callback */
8070 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
8071 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8072 }
8073
8074 /* ISR controller transmission */
8075 return (I3C_Ctrl_Tx_ISR(hi3c, itMasks));
8076 }
8077
8078 /**
8079 * @brief Interrupt Sub-Routine which handles controller reception and Controller received events in interrupt mode.
8080 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8081 * for the specified I3C.
8082 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8083 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8084 */
I3C_Ctrl_Rx_Listen_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8085 static HAL_StatusTypeDef I3C_Ctrl_Rx_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8086 {
8087 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
8088 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
8089 {
8090 /* Clear IBI request flag */
8091 LL_I3C_ClearFlag_IBI(hi3c->Instance);
8092
8093 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8094 /* Call registered callback */
8095 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
8096 #else
8097 /* Asynchronous IBI event Callback */
8098 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
8099 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8100 }
8101
8102 /* I3C controller controller-role request event management ---------------------------------------------------------*/
8103 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
8104 {
8105 /* Clear controller-role request flag */
8106 LL_I3C_ClearFlag_CR(hi3c->Instance);
8107
8108 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8109 /* Call registered callback */
8110 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
8111 #else
8112 /* Asynchronous controller-role event Callback */
8113 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
8114 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8115 }
8116
8117 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
8118 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
8119 {
8120 /* Clear hot-join flag */
8121 LL_I3C_ClearFlag_HJ(hi3c->Instance);
8122
8123 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8124 /* Call registered callback */
8125 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
8126 #else
8127 /* Asynchronous hot-join event Callback */
8128 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
8129 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8130 }
8131
8132 /* ISR controller reception */
8133 return (I3C_Ctrl_Rx_ISR(hi3c, itMasks));
8134 }
8135
8136 /**
8137 * @brief Interrupt Sub-Routine which handles controller multiple transmission/reception and
8138 * Controller received eventsin interrupt mode.
8139 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8140 * for the specified I3C.
8141 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8142 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8143 */
I3C_Ctrl_Multiple_Xfer_Listen_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8144 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8145 {
8146 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
8147 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
8148 {
8149 /* Clear IBI request flag */
8150 LL_I3C_ClearFlag_IBI(hi3c->Instance);
8151
8152 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8153 /* Call registered callback */
8154 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
8155 #else
8156 /* Asynchronous IBI event Callback */
8157 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
8158 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8159 }
8160
8161 /* I3C controller controller-role request event management ---------------------------------------------------------*/
8162 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
8163 {
8164 /* Clear controller-role request flag */
8165 LL_I3C_ClearFlag_CR(hi3c->Instance);
8166
8167 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8168 /* Call registered callback */
8169 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
8170 #else
8171 /* Asynchronous controller-role event Callback */
8172 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
8173 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8174 }
8175
8176 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
8177 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
8178 {
8179 /* Clear hot-join flag */
8180 LL_I3C_ClearFlag_HJ(hi3c->Instance);
8181
8182 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8183 /* Call registered callback */
8184 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
8185 #else
8186 /* Asynchronous hot-join event Callback */
8187 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
8188 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8189 }
8190
8191 /* ISR controller transmission/reception */
8192 return (I3C_Ctrl_Multiple_Xfer_ISR(hi3c, itMasks));
8193 }
8194 /**
8195 * @brief Interrupt Sub-Routine which handles controller CCC Dynamic Address Assignment command in interrupt mode.
8196 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8197 * for the specified I3C.
8198 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8199 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8200 */
I3C_Ctrl_DAA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8201 static HAL_StatusTypeDef I3C_Ctrl_DAA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8202 {
8203 uint64_t target_payload = 0U;
8204
8205 /* Check that a Dynamic Address Assignment process is ongoing */
8206 if (hi3c->State == HAL_I3C_STATE_BUSY_DAA)
8207 {
8208 /* I3C Control FIFO not full interrupt Check */
8209 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
8210 {
8211 /* Write ENTDAA CCC information in the control register */
8212 LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_ENTDAA, 0U, LL_I3C_GENERATE_STOP);
8213 }
8214
8215 /* I3C Tx FIFO not full interrupt Check */
8216 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
8217 {
8218 /* Check on the Rx FIFO threshold to know the Dynamic Address Assignment treatment process : byte or word */
8219 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
8220 {
8221 /* For loop to get target payload */
8222 for (uint32_t index = 0U; index < 8U; index++)
8223 {
8224 /* Retrieve payload byte by byte */
8225 target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData8(hi3c->Instance) << (index * 8U));
8226 }
8227 }
8228 else
8229 {
8230 /* Retrieve first 32 bits payload */
8231 target_payload = (uint64_t)LL_I3C_ReceiveData32(hi3c->Instance);
8232
8233 /* Retrieve second 32 bits payload */
8234 target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData32(hi3c->Instance) << 32U);
8235 }
8236
8237 /* Call the corresponding callback */
8238 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8239 hi3c->TgtReqDynamicAddrCallback(hi3c, target_payload);
8240 #else
8241 HAL_I3C_TgtReqDynamicAddrCallback(hi3c, target_payload);
8242 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
8243 }
8244
8245 /* I3C frame complete event Check */
8246 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8247 {
8248 /* Clear frame complete flag */
8249 LL_I3C_ClearFlag_FC(hi3c->Instance);
8250
8251 /* Disable Dynamic Address Assignment process interrupts */
8252 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_DAA_IT);
8253
8254 /* Update handle state parameter */
8255 I3C_StateUpdate(hi3c);
8256
8257 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8258
8259 /* Call the Dynamic Address Assignment complete callback */
8260 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8261 hi3c->CtrlDAACpltCallback(hi3c);
8262 #else
8263 HAL_I3C_CtrlDAACpltCallback(hi3c);
8264 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8265 }
8266 }
8267 return HAL_OK;
8268 }
8269
8270 #if defined(HAL_DMA_MODULE_ENABLED)
8271 /**
8272 * @brief Interrupt Sub-Routine which handles controller transmit data in DMA mode.
8273 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8274 * for the specified I3C.
8275 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8276 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8277 */
I3C_Ctrl_Tx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8278 static HAL_StatusTypeDef I3C_Ctrl_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8279 {
8280 /* Check that a Tx process is ongoing */
8281 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
8282 {
8283 /* I3C target frame complete event Check */
8284 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8285 {
8286 /* Clear frame complete flag */
8287 LL_I3C_ClearFlag_FC(hi3c->Instance);
8288
8289 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U)
8290 {
8291 /* Check if all data bytes are transmitted */
8292 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U)
8293 {
8294 /* Disable Tx process interrupts */
8295 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
8296
8297 /* Update handle state parameter */
8298 I3C_StateUpdate(hi3c);
8299
8300 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8301
8302 /* Update the number of remaining data bytes */
8303 hi3c->TxXferCount = 0U;
8304
8305 /* Call controller transmit complete callback to inform upper layer of End of Transfer */
8306 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8307 hi3c->CtrlTxCpltCallback(hi3c);
8308 #else
8309 HAL_I3C_CtrlTxCpltCallback(hi3c);
8310 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8311 }
8312 else
8313 {
8314 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8315
8316 /* Call error treatment function */
8317 I3C_ErrorTreatment(hi3c);
8318 }
8319 }
8320 else
8321 {
8322 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8323
8324 /* Call the transmit complete callback */
8325 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8326 hi3c->CtrlTxCpltCallback(hi3c);
8327 #else
8328 HAL_I3C_CtrlTxCpltCallback(hi3c);
8329 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8330
8331 /* Then Initiate a Start condition */
8332 LL_I3C_RequestTransfer(hi3c->Instance);
8333 }
8334 }
8335 }
8336 return HAL_OK;
8337 }
8338
8339 /**
8340 * @brief Interrupt Sub-Routine which handles controller receive data in DMA mode.
8341 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8342 * for the specified I3C.
8343 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8344 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8345 */
I3C_Ctrl_Rx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8346 static HAL_StatusTypeDef I3C_Ctrl_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8347 {
8348 /* Check that an Rx process is ongoing */
8349 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
8350 {
8351 /* I3C target frame complete event Check */
8352 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8353 {
8354 /* Clear frame complete flag */
8355 LL_I3C_ClearFlag_FC(hi3c->Instance);
8356
8357 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U)
8358 {
8359 /* Check if all data bytes are received */
8360 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U)
8361 {
8362 /* Disable Rx process interrupts */
8363 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
8364
8365 /* Update handle state parameter */
8366 I3C_StateUpdate(hi3c);
8367
8368 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8369
8370 /* Update the number of remaining data bytes */
8371 hi3c->RxXferCount = 0U;
8372
8373 /* Call controller receive complete callback */
8374 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8375 hi3c->CtrlRxCpltCallback(hi3c);
8376 #else
8377 HAL_I3C_CtrlRxCpltCallback(hi3c);
8378 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8379 }
8380 else
8381 {
8382 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8383
8384 /* Call error treatment function */
8385 I3C_ErrorTreatment(hi3c);
8386 }
8387 }
8388 else
8389 {
8390 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8391
8392 /* Call the receive complete callback */
8393 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8394 hi3c->CtrlRxCpltCallback(hi3c);
8395 #else
8396 HAL_I3C_CtrlRxCpltCallback(hi3c);
8397 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8398
8399 /* Then Initiate a Start condition */
8400 LL_I3C_RequestTransfer(hi3c->Instance);
8401 }
8402 }
8403 }
8404 return HAL_OK;
8405 }
8406
8407 /**
8408 * @brief Interrupt Sub-Routine which handles controller multiple receive and transmit data in DMA mode.
8409 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8410 * for the specified I3C.
8411 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8412 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8413 */
I3C_Ctrl_Multiple_Xfer_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8414 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8415 {
8416 /* Check that an Rx or Tx process is ongoing */
8417 if (hi3c->State == HAL_I3C_STATE_BUSY_TX_RX)
8418 {
8419 /* I3C target frame complete event Check */
8420 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8421 {
8422 /* Clear frame complete flag */
8423 LL_I3C_ClearFlag_FC(hi3c->Instance);
8424
8425 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U)
8426 {
8427 /* Check if all data bytes are received or transmitted */
8428 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U)
8429 {
8430 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U)
8431 {
8432 /* Disable transfer Tx/Rx process interrupts */
8433 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
8434
8435 /* Update handle state parameter */
8436 I3C_StateUpdate(hi3c);
8437
8438 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8439
8440 /* Update the number of remaining data bytes */
8441 hi3c->RxXferCount = 0U;
8442
8443 /* Update the number of remaining data bytes */
8444 hi3c->TxXferCount = 0U;
8445
8446 /* Call controller transmit, receive complete callback to inform upper layer of End of Transfer */
8447 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8448 hi3c->CtrlMultipleXferCpltCallback(hi3c);
8449 #else
8450 HAL_I3C_CtrlMultipleXferCpltCallback(hi3c);
8451 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8452 }
8453 else
8454 {
8455 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8456
8457 /* Call error treatment function */
8458 I3C_ErrorTreatment(hi3c);
8459 }
8460 }
8461 else
8462 {
8463 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8464
8465 /* Call error treatment function */
8466 I3C_ErrorTreatment(hi3c);
8467 }
8468 }
8469 else
8470 {
8471 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8472
8473 /* Then Initiate a Start condition */
8474 LL_I3C_RequestTransfer(hi3c->Instance);
8475 }
8476 }
8477 }
8478 return HAL_OK;
8479 }
8480 #endif /* HAL_DMA_MODULE_ENABLED */
8481
8482 /**
8483 * @brief Interrupt Sub-Routine which handles abort process in interrupt mode.
8484 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8485 * for the specified I3C.
8486 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8487 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8488 */
I3C_Abort_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8489 static HAL_StatusTypeDef I3C_Abort_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8490 {
8491 /* Check that an Abort process is ongoing */
8492 if (hi3c->State == HAL_I3C_STATE_ABORT)
8493 {
8494 /* I3C Rx FIFO not empty interrupt Check */
8495 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
8496 {
8497 if (LL_I3C_IsActiveFlag_DOVR(hi3c->Instance) == 1U)
8498 {
8499 /* Flush remaining Rx data */
8500 LL_I3C_RequestRxFIFOFlush(hi3c->Instance);
8501 }
8502 }
8503
8504 /* I3C Abort frame complete event Check */
8505 /* Evenif abort is called, the Frame completion can arrive if abort is requested at the end of the processus */
8506 /* Evenif completion occurs, treat this end of processus as abort completion process */
8507 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8508 {
8509 /* Clear frame complete flag */
8510 LL_I3C_ClearFlag_FC(hi3c->Instance);
8511
8512 /* Call error treatment function */
8513 I3C_ErrorTreatment(hi3c);
8514 }
8515 }
8516 return HAL_OK;
8517 }
8518
8519 #if defined(HAL_DMA_MODULE_ENABLED)
8520 /**
8521 * @brief DMA I3C control transmit process complete callback.
8522 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8523 * for the specified DMA channel.
8524 * @retval None
8525 */
I3C_DMAControlTransmitCplt(DMA_HandleTypeDef * hdma)8526 static void I3C_DMAControlTransmitCplt(DMA_HandleTypeDef *hdma)
8527 {
8528 /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */
8529 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8530
8531 /* Disable control DMA Request */
8532 LL_I3C_DisableDMAReq_Control(hi3c->Instance);
8533 }
8534
8535 /**
8536 * @brief DMA I3C transmit data process complete callback.
8537 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8538 * for the specified DMA channel.
8539 * @retval None
8540 */
I3C_DMADataTransmitCplt(DMA_HandleTypeDef * hdma)8541 static void I3C_DMADataTransmitCplt(DMA_HandleTypeDef *hdma)
8542 {
8543 /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */
8544 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8545
8546 /* Disable Tx DMA Request */
8547 LL_I3C_DisableDMAReq_TX(hi3c->Instance);
8548 }
8549
8550 /**
8551 * @brief DMA I3C receive data process complete callback.
8552 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8553 * for the specified DMA channel.
8554 * @retval None
8555 */
I3C_DMADataReceiveCplt(DMA_HandleTypeDef * hdma)8556 static void I3C_DMADataReceiveCplt(DMA_HandleTypeDef *hdma)
8557 {
8558 /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */
8559 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8560
8561 /* Disable Rx DMA Request */
8562 LL_I3C_DisableDMAReq_RX(hi3c->Instance);
8563 }
8564
8565 /**
8566 * @brief DMA I3C communication error callback.
8567 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8568 * for the specified DMA channel.
8569 * @retval None
8570 */
I3C_DMAError(DMA_HandleTypeDef * hdma)8571 static void I3C_DMAError(DMA_HandleTypeDef *hdma)
8572 {
8573 /* Just to solve MisraC error then to be removed */
8574 /* Derogation MISRAC2012-Rule-11.5 */
8575 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8576
8577 hi3c->ErrorCode |= HAL_I3C_ERROR_DMA;
8578 }
8579
8580 /**
8581 * @brief DMA I3C communication abort callback to be called at end of DMA Abort procedure.
8582 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8583 * for the specified DMA channel.
8584 * @retval None
8585 */
I3C_DMAAbort(DMA_HandleTypeDef * hdma)8586 static void I3C_DMAAbort(DMA_HandleTypeDef *hdma)
8587 {
8588 /* Derogation MISRAC2012-Rule-11.5 */
8589 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8590
8591 /* Reset Tx DMA AbortCpltCallback */
8592 if (hi3c->hdmatx != NULL)
8593 {
8594 hi3c->hdmatx->XferAbortCallback = NULL;
8595 }
8596
8597 /* Reset Rx DMA AbortCpltCallback */
8598 if (hi3c->hdmarx != NULL)
8599 {
8600 hi3c->hdmarx->XferAbortCallback = NULL;
8601 }
8602
8603 /* Reset control DMA AbortCpltCallback */
8604 if (hi3c->hdmacr != NULL)
8605 {
8606 hi3c->hdmacr->XferAbortCallback = NULL;
8607 }
8608
8609 I3C_TreatErrorCallback(hi3c);
8610 }
8611 #endif /* HAL_DMA_MODULE_ENABLED */
8612
8613 /**
8614 * @brief This function handles I3C Communication Timeout.
8615 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8616 * information for the specified I3C.
8617 * @param flag : [IN] Specifies the I3C flag to check.
8618 * @param flagstatus : [IN] The new Flag status (SET or RESET).
8619 * @param timeout : [IN] Timeout duration in millisecond.
8620 * @param tickstart : [IN] Tick start value
8621 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8622 */
I3C_WaitOnFlagUntilTimeout(I3C_HandleTypeDef * hi3c,uint32_t flag,FlagStatus flagstatus,uint32_t timeout,uint32_t tickstart)8623 static HAL_StatusTypeDef I3C_WaitOnFlagUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t flag, FlagStatus flagstatus,
8624 uint32_t timeout, uint32_t tickstart)
8625 {
8626 HAL_StatusTypeDef status = HAL_OK;
8627
8628 while ((__HAL_I3C_GET_FLAG(hi3c, flag) == flagstatus) && (status == HAL_OK))
8629 {
8630 /* Check for the Timeout */
8631 if (timeout != HAL_MAX_DELAY)
8632 {
8633 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
8634 {
8635 if (__HAL_I3C_GET_FLAG(hi3c, flag) == flagstatus)
8636 {
8637 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
8638 status = HAL_TIMEOUT;
8639 }
8640 }
8641 }
8642
8643 /* Check if an error occurs during Flag waiting */
8644 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
8645 {
8646 /* Clear error flag */
8647 LL_I3C_ClearFlag_ERR(hi3c->Instance);
8648
8649 /* Update handle error code parameter */
8650 I3C_GetErrorSources(hi3c);
8651
8652 status = HAL_ERROR;
8653 }
8654 }
8655 return status;
8656 }
8657
8658 /**
8659 * @brief This function handles I3C Dynamic Address Assignment timeout.
8660 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8661 * information for the specified I3C.
8662 * @param timeout : [IN] Timeout duration in millisecond.
8663 * @param tickstart : [IN] Tick start value
8664 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8665 */
I3C_WaitOnDAAUntilTimeout(I3C_HandleTypeDef * hi3c,uint32_t timeout,uint32_t tickstart)8666 static HAL_StatusTypeDef I3C_WaitOnDAAUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t timeout, uint32_t tickstart)
8667 {
8668 HAL_StatusTypeDef status = HAL_OK;
8669 uint32_t active_flags = READ_REG(hi3c->Instance->EVR);
8670
8671 while (((active_flags & (HAL_I3C_FLAG_FCF | HAL_I3C_FLAG_TXFNFF)) == 0U) && (status == HAL_OK))
8672 {
8673 /* Check for the Timeout */
8674 if (timeout != HAL_MAX_DELAY)
8675 {
8676 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
8677 {
8678 if ((active_flags & (HAL_I3C_FLAG_FCF | HAL_I3C_FLAG_TXFNFF)) == 0U)
8679 {
8680 hi3c->ErrorCode |= HAL_I3C_ERROR_TIMEOUT;
8681 status = HAL_TIMEOUT;
8682 }
8683 }
8684 }
8685
8686 /* Check if an error occurs during Flag waiting */
8687 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
8688 {
8689 /* Clear error flag */
8690 LL_I3C_ClearFlag_ERR(hi3c->Instance);
8691
8692 /* Update handle error code parameter */
8693 I3C_GetErrorSources(hi3c);
8694
8695 status = HAL_ERROR;
8696 }
8697
8698 /* Read active flags from EVR register */
8699 active_flags = READ_REG(hi3c->Instance->EVR);
8700 }
8701 return status;
8702 }
8703
8704 /**
8705 * @brief I3C transmit by byte.
8706 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8707 * information for the specified I3C.
8708 * @retval None
8709 */
I3C_TransmitByteTreatment(I3C_HandleTypeDef * hi3c)8710 static void I3C_TransmitByteTreatment(I3C_HandleTypeDef *hi3c)
8711 {
8712 /* Check TX FIFO not full flag */
8713 while ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET) && (hi3c->TxXferCount > 0U))
8714 {
8715 /* Write Tx buffer data to transmit register */
8716 LL_I3C_TransmitData8(hi3c->Instance, *hi3c->pXferData->TxBuf.pBuffer);
8717
8718 /* Increment Buffer pointer */
8719 hi3c->pXferData->TxBuf.pBuffer++;
8720
8721 /* Decrement remaining bytes counter */
8722 hi3c->TxXferCount--;
8723 }
8724 }
8725
8726 /**
8727 * @brief I3C transmit by word.
8728 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8729 * information for the specified I3C.
8730 * @retval None
8731 */
I3C_TransmitWordTreatment(I3C_HandleTypeDef * hi3c)8732 static void I3C_TransmitWordTreatment(I3C_HandleTypeDef *hi3c)
8733 {
8734 /* Check TX FIFO not full flag */
8735 while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET)
8736 {
8737 /* Write Tx buffer data to transmit register */
8738 LL_I3C_TransmitData32(hi3c->Instance, *((uint32_t *)hi3c->pXferData->TxBuf.pBuffer));
8739
8740 /* Increment Buffer pointer */
8741 hi3c->pXferData->TxBuf.pBuffer += sizeof(uint32_t);
8742
8743 if (hi3c->TxXferCount < sizeof(uint32_t))
8744 {
8745 hi3c->TxXferCount = 0U;
8746 }
8747 else
8748 {
8749 /* Decrement remaining bytes counter */
8750 hi3c->TxXferCount -= sizeof(uint32_t);
8751 }
8752 }
8753 }
8754
8755 /**
8756 * @brief I3C receive by byte.
8757 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8758 * information for the specified I3C.
8759 * @retval None
8760 */
I3C_ReceiveByteTreatment(I3C_HandleTypeDef * hi3c)8761 static void I3C_ReceiveByteTreatment(I3C_HandleTypeDef *hi3c)
8762 {
8763 /* Check RX FIFO not empty flag */
8764 while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_RXFNEF) == SET)
8765 {
8766 /* Store received bytes in the Rx buffer */
8767 *hi3c->pXferData->RxBuf.pBuffer = LL_I3C_ReceiveData8(hi3c->Instance);
8768
8769 /* Increment Buffer pointer */
8770 hi3c->pXferData->RxBuf.pBuffer++;
8771
8772 /* Decrement remaining bytes counter */
8773 hi3c->RxXferCount--;
8774 }
8775 }
8776
8777 /**
8778 * @brief I3C receive by word.
8779 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8780 * information for the specified I3C.
8781 * @retval None
8782 */
I3C_ReceiveWordTreatment(I3C_HandleTypeDef * hi3c)8783 static void I3C_ReceiveWordTreatment(I3C_HandleTypeDef *hi3c)
8784 {
8785 /* Check RX FIFO not empty flag */
8786 while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_RXFNEF) == SET)
8787 {
8788 /* Store received bytes in the Rx buffer */
8789 *((uint32_t *)hi3c->pXferData->RxBuf.pBuffer) = LL_I3C_ReceiveData32(hi3c->Instance);
8790
8791 /* Increment Buffer pointer */
8792 hi3c->pXferData->RxBuf.pBuffer += sizeof(uint32_t);
8793
8794 if (hi3c->RxXferCount > sizeof(uint32_t))
8795 {
8796 /* Decrement remaining bytes counter */
8797 hi3c->RxXferCount -= sizeof(uint32_t);
8798 }
8799 else
8800 {
8801 /* Reset counter as last modulo word Rx data received */
8802 hi3c->RxXferCount = 0U;
8803 }
8804 }
8805 }
8806
8807 /**
8808 * @brief I3C Control data treatment.
8809 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8810 * information for the specified I3C.
8811 * @retval None
8812 */
I3C_ControlDataTreatment(I3C_HandleTypeDef * hi3c)8813 static void I3C_ControlDataTreatment(I3C_HandleTypeDef *hi3c)
8814 {
8815 /* Check if Control FIFO requests data */
8816 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_CFNFF) == SET)
8817 {
8818 /* Decrement remaining control buffer data counter */
8819 hi3c->ControlXferCount--;
8820
8821 /* Write Control buffer data to control register */
8822 WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer);
8823
8824 /* Increment Buffer pointer */
8825 hi3c->pXferData->CtrlBuf.pBuffer++;
8826 }
8827 }
8828
8829 /**
8830 * @brief I3C state update.
8831 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8832 * information for the specified I3C.
8833 * @retval None
8834 */
I3C_StateUpdate(I3C_HandleTypeDef * hi3c)8835 static void I3C_StateUpdate(I3C_HandleTypeDef *hi3c)
8836 {
8837 /* Check on previous state */
8838 if (hi3c->PreviousState == HAL_I3C_STATE_LISTEN)
8839 {
8840 /* Set state to listen */
8841 hi3c->State = HAL_I3C_STATE_LISTEN;
8842
8843 /* Check the I3C mode */
8844 if (hi3c->Mode == HAL_I3C_MODE_TARGET)
8845 {
8846 /* Store the target event treatment function */
8847 hi3c->XferISR = I3C_Tgt_Event_ISR;
8848 }
8849 else
8850 {
8851 /* Store the controller event treatment function */
8852 hi3c->XferISR = I3C_Ctrl_Event_ISR;
8853 }
8854 }
8855 else
8856 {
8857 /* Set state to ready */
8858 hi3c->State = HAL_I3C_STATE_READY;
8859
8860 /* Reset XferISR */
8861 hi3c->XferISR = NULL;
8862 }
8863 }
8864
8865 /**
8866 * @brief I3C get error source.
8867 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8868 * information for the specified I3C.
8869 * @retval None
8870 */
I3C_GetErrorSources(I3C_HandleTypeDef * hi3c)8871 static void I3C_GetErrorSources(I3C_HandleTypeDef *hi3c)
8872 {
8873 /* Check on the I3C mode */
8874 switch (hi3c->Mode)
8875 {
8876 case HAL_I3C_MODE_CONTROLLER:
8877 {
8878 /* I3C data error during controller-role hand-off procedure */
8879 if (LL_I3C_IsActiveFlag_DERR(hi3c->Instance) == 1U)
8880 {
8881 hi3c->ErrorCode |= HAL_I3C_ERROR_DATA_HAND_OFF;
8882 }
8883
8884 /* I3C data not acknowledged error */
8885 if (LL_I3C_IsActiveFlag_DNACK(hi3c->Instance) == 1U)
8886 {
8887 hi3c->ErrorCode |= HAL_I3C_ERROR_DATA_NACK;
8888 }
8889
8890 /* I3C address not acknowledged error */
8891 if (LL_I3C_IsActiveFlag_ANACK(hi3c->Instance) == 1U)
8892 {
8893 hi3c->ErrorCode |= HAL_I3C_ERROR_ADDRESS_NACK;
8894 }
8895
8896 /* I3C Status FIFO Over-Run or Control FIFO Under-Run error */
8897 if (LL_I3C_IsActiveFlag_COVR(hi3c->Instance) == 1U)
8898 {
8899 hi3c->ErrorCode |= HAL_I3C_ERROR_COVR;
8900 }
8901
8902 break;
8903 }
8904
8905 case HAL_I3C_MODE_TARGET:
8906 {
8907 /* I3C SCL stall error */
8908 if (LL_I3C_IsActiveFlag_STALL(hi3c->Instance) == 1U)
8909 {
8910 hi3c->ErrorCode |= HAL_I3C_ERROR_STALL;
8911 }
8912
8913 break;
8914 }
8915
8916 default:
8917 {
8918 break;
8919 }
8920 }
8921
8922 /* I3C Rx FIFO Over-Run or Tx FIFO Under-Run error */
8923 if (LL_I3C_IsActiveFlag_DOVR(hi3c->Instance) == 1U)
8924 {
8925 hi3c->ErrorCode |= HAL_I3C_ERROR_DOVR;
8926 }
8927
8928 /* I3C Protocol error */
8929 if (LL_I3C_IsActiveFlag_PERR(hi3c->Instance) == 1U)
8930 {
8931 hi3c->ErrorCode |= (I3C_SER_PERR | LL_I3C_GetMessageErrorCode(hi3c->Instance));
8932 }
8933 }
8934
8935 /**
8936 * @brief I3C transfer prior preparation.
8937 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8938 * information for the specified I3C.
8939 * @param counter : [IN] Number of devices or commands to treat.
8940 * @param option : [IN] Parameter indicates the transfer option.
8941 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8942 */
I3C_Xfer_PriorPreparation(I3C_HandleTypeDef * hi3c,uint8_t counter,uint32_t option)8943 static HAL_StatusTypeDef I3C_Xfer_PriorPreparation(I3C_HandleTypeDef *hi3c, uint8_t counter, uint32_t option)
8944 {
8945 HAL_StatusTypeDef status = HAL_OK;
8946 uint32_t current_tx_index = 0U;
8947 uint32_t global_tx_size = 0U;
8948 uint32_t global_rx_size = 0U;
8949 uint32_t nb_tx_frame = 0U;
8950 uint32_t direction;
8951
8952 for (uint32_t descr_index = 0U; descr_index < counter; descr_index++)
8953 {
8954 /* Direct CCC command */
8955 if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT)
8956 {
8957 /* Update direction of frame */
8958 direction = hi3c->pCCCDesc[descr_index].Direction;
8959
8960 /* Direction read with Define byte */
8961 if (((option & I3C_DEFINE_BYTE_MASK) != 0U) && (direction == HAL_I3C_DIRECTION_READ))
8962 {
8963 nb_tx_frame += 1U;
8964
8965 global_tx_size += 1U;
8966
8967 global_rx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size - 1U;
8968
8969 /* Check on the global size and on the Tx buffer pointer */
8970 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
8971 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
8972 (hi3c->pXferData->TxBuf.pBuffer == NULL))
8973 {
8974 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
8975
8976 status = HAL_ERROR;
8977 }
8978 else
8979 {
8980 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
8981 current_tx_index = I3C_FillTxBuffer_CCC(hi3c, descr_index, 1U, current_tx_index);
8982 }
8983 }
8984 else if (direction == HAL_I3C_DIRECTION_WRITE)
8985 {
8986 nb_tx_frame += 1U;
8987
8988 global_tx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size;
8989
8990 /* Check on the global size and on the Tx buffer pointer */
8991 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
8992 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
8993 (hi3c->pXferData->TxBuf.pBuffer == NULL))
8994 {
8995 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
8996
8997 status = HAL_ERROR;
8998 }
8999 else
9000 {
9001 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
9002 current_tx_index = I3C_FillTxBuffer_CCC(hi3c,
9003 descr_index,
9004 hi3c->pCCCDesc[descr_index].CCCBuf.Size,
9005 current_tx_index);
9006 }
9007 }
9008 /* Direction read without Define byte */
9009 else
9010 {
9011 global_rx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size;
9012 }
9013 }
9014 /* Broadcast CCC command */
9015 else if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC)
9016 {
9017 /* Update direction of frame */
9018 direction = hi3c->pCCCDesc[descr_index].Direction;
9019
9020 if (direction == HAL_I3C_DIRECTION_WRITE)
9021 {
9022 nb_tx_frame += 1U;
9023
9024 global_tx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size;
9025
9026 /* Check on the global size and on the Tx buffer pointer */
9027 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
9028 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
9029 (hi3c->pXferData->TxBuf.pBuffer == NULL))
9030 {
9031 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9032
9033 status = HAL_ERROR;
9034 }
9035 else
9036 {
9037 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
9038 current_tx_index = I3C_FillTxBuffer_CCC(hi3c,
9039 descr_index,
9040 hi3c->pCCCDesc[descr_index].CCCBuf.Size,
9041 current_tx_index);
9042 }
9043 }
9044 else
9045 {
9046 status = HAL_ERROR;
9047 }
9048 }
9049 /* Private */
9050 else
9051 {
9052 /* Update direction of frame */
9053 direction = hi3c->pPrivateDesc[descr_index].Direction;
9054
9055 if (direction == HAL_I3C_DIRECTION_WRITE)
9056 {
9057 nb_tx_frame += 1U;
9058
9059 global_tx_size += hi3c->pPrivateDesc[descr_index].TxBuf.Size;
9060
9061 /* Check on the global size and on the Tx buffer pointer */
9062 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
9063 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
9064 (hi3c->pXferData->TxBuf.pBuffer == NULL))
9065 {
9066 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9067
9068 status = HAL_ERROR;
9069 }
9070 else
9071 {
9072 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
9073 current_tx_index = I3C_FillTxBuffer_Private(hi3c,
9074 descr_index,
9075 hi3c->pPrivateDesc[descr_index].TxBuf.Size,
9076 current_tx_index);
9077 }
9078 }
9079 else
9080 {
9081 global_rx_size += hi3c->pPrivateDesc[descr_index].RxBuf.Size;
9082 }
9083 }
9084
9085 /* Check if there is an error in the Tx Buffer*/
9086 if (status == HAL_ERROR)
9087 {
9088 break;
9089 }
9090 }
9091
9092 if (status == HAL_OK)
9093 {
9094 /* Check on the Tx threshold and the number of Tx frame */
9095 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_4_4)
9096 {
9097 /* LL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
9098 multiple transmission frames */
9099 if (nb_tx_frame > 1U)
9100 {
9101 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
9102 status = HAL_ERROR;
9103 }
9104 }
9105 }
9106
9107 if (status == HAL_OK)
9108 {
9109 /* Check on the size Rx buffer */
9110 if (global_rx_size > hi3c->pXferData->RxBuf.Size)
9111 {
9112 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9113 status = HAL_ERROR;
9114 }
9115 else
9116 {
9117 hi3c->RxXferCount = global_rx_size;
9118 }
9119
9120 /* Set handle transfer parameters */
9121 hi3c->TxXferCount = global_tx_size;
9122 }
9123
9124 return status;
9125 }
9126
9127 /**
9128 * @brief I3C fill Tx Buffer with data from CCC Descriptor.
9129 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9130 * information for the specified I3C.
9131 * @param indexDesc : [IN] Index of descriptor.
9132 * @param txSize : [IN] Size of Tx data.
9133 * @param txCurrentIndex : [IN] Current Index of TxBuffer.
9134 * @retval index_tx : [OUT] New current Index of TxBuffer.
9135 */
I3C_FillTxBuffer_CCC(I3C_HandleTypeDef * hi3c,uint32_t indexDesc,uint32_t txSize,uint32_t txCurrentIndex)9136 static uint32_t I3C_FillTxBuffer_CCC(I3C_HandleTypeDef *hi3c,
9137 uint32_t indexDesc,
9138 uint32_t txSize,
9139 uint32_t txCurrentIndex)
9140 {
9141 uint32_t index_tx = txCurrentIndex;
9142
9143 for (uint32_t index = 0U; index < txSize; index++)
9144 {
9145 hi3c->pXferData->TxBuf.pBuffer[index_tx] = hi3c->pCCCDesc[indexDesc].CCCBuf.pBuffer[index];
9146
9147 index_tx++;
9148 }
9149
9150 return index_tx;
9151 }
9152
9153 /**
9154 * @brief I3C fill Tx Buffer with data from Private Descriptor.
9155 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9156 * information for the specified I3C.
9157 * @param indexDesc : [IN] Index of descriptor.
9158 * @param txSize : [IN] Size of Tx data.
9159 * @param txCurrentIndex : [IN] Current Index of TxBuffer.
9160 * @retval index_tx : [OUT] New current Index of TxBuffer.
9161 */
I3C_FillTxBuffer_Private(I3C_HandleTypeDef * hi3c,uint32_t indexDesc,uint32_t txSize,uint32_t txCurrentIndex)9162 static uint32_t I3C_FillTxBuffer_Private(I3C_HandleTypeDef *hi3c,
9163 uint32_t indexDesc,
9164 uint32_t txSize,
9165 uint32_t txCurrentIndex)
9166 {
9167 uint32_t index_tx = txCurrentIndex;
9168
9169 for (uint32_t index = 0U; index < txSize; index++)
9170 {
9171 hi3c->pXferData->TxBuf.pBuffer[index_tx] = hi3c->pPrivateDesc[indexDesc].TxBuf.pBuffer[index];
9172
9173 index_tx++;
9174 }
9175
9176 return index_tx;
9177 }
9178
9179 /**
9180 * @brief I3C Control buffer prior preparation.
9181 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9182 * information for the specified I3C.
9183 * @param counter : [IN] Number of devices or commands to treat.
9184 * @param option : [IN] Parameter indicates the transfer option.
9185 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
9186 */
I3C_ControlBuffer_PriorPreparation(I3C_HandleTypeDef * hi3c,uint8_t counter,uint32_t option)9187 static HAL_StatusTypeDef I3C_ControlBuffer_PriorPreparation(I3C_HandleTypeDef *hi3c,
9188 uint8_t counter,
9189 uint32_t option)
9190 {
9191 HAL_StatusTypeDef status = HAL_OK;
9192 uint32_t nb_define_bytes;
9193 uint32_t stop_condition;
9194 uint32_t nb_data_bytes;
9195 uint32_t index;
9196
9197 /* Check on the control buffer pointer */
9198 if (hi3c->pXferData->CtrlBuf.pBuffer == NULL)
9199 {
9200 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9201 status = HAL_ERROR;
9202 }
9203 else
9204 {
9205 /* Extract from option required information */
9206 nb_define_bytes = (option & I3C_DEFINE_BYTE_MASK);
9207 stop_condition = (option & I3C_RESTART_STOP_MASK);
9208
9209 /* Check on the deactivation of the arbitration */
9210 if ((option & I3C_ARBITRATION_HEADER_MASK) == I3C_ARBITRATION_HEADER_MASK)
9211 {
9212 /* Disable arbitration header */
9213 LL_I3C_DisableArbitrationHeader(hi3c->Instance);
9214 }
9215 else
9216 {
9217 /* Enable arbitration header */
9218 LL_I3C_EnableArbitrationHeader(hi3c->Instance);
9219 }
9220
9221 /* Check on the operation type */
9222 if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC)
9223 {
9224 /*------------------------------------------ Broadcast CCC -----------------------------------------------------*/
9225 /* Check on the control buffer size */
9226 if (hi3c->pXferData->CtrlBuf.Size < (uint32_t)counter)
9227 {
9228 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9229 status = HAL_ERROR;
9230 }
9231 else
9232 {
9233 /* Set remaining control buffer data counter */
9234 hi3c->ControlXferCount = (uint32_t)counter;
9235
9236 /* For loop on the number of commands */
9237 for (index = 0U; index < ((uint32_t)counter - 1U); index++)
9238 {
9239 /* Update control buffer value */
9240 hi3c->pXferData->CtrlBuf.pBuffer[index] = ((uint32_t)hi3c->pCCCDesc[index].CCCBuf.Size |
9241 ((uint32_t)hi3c->pCCCDesc[index].CCC << I3C_CR_CCC_Pos) |
9242 LL_I3C_CONTROLLER_MTYPE_CCC | stop_condition);
9243 }
9244
9245 /* At the last device we should generate a stop condition */
9246 hi3c->pXferData->CtrlBuf.pBuffer[index] = ((uint32_t)hi3c->pCCCDesc[index].CCCBuf.Size |
9247 ((uint32_t)hi3c->pCCCDesc[index].CCC << I3C_CR_CCC_Pos) |
9248 LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_STOP);
9249 }
9250 }
9251 else if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT)
9252 {
9253 /*------------------------------------------ Direct CCC --------------------------------------------------------*/
9254 /* Check on the control buffer size */
9255 if (hi3c->pXferData->CtrlBuf.Size < ((uint32_t)counter * 2U))
9256 {
9257 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9258 status = HAL_ERROR;
9259 }
9260 else
9261 {
9262 /* Set remaining control buffer data counter */
9263 hi3c->ControlXferCount = ((uint32_t)counter * 2U);
9264
9265 /* For loop on the number of (devices or commands) * 2 */
9266 for (index = 0U; index < (((uint32_t)counter * 2U) - 2U); index += 2U)
9267 {
9268 /* Step 1 : update control buffer value for the CCC command */
9269 hi3c->pXferData->CtrlBuf.pBuffer[index] = (nb_define_bytes |
9270 ((uint32_t)hi3c->pCCCDesc[index / 2U].CCC << I3C_CR_CCC_Pos) |
9271 LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_RESTART);
9272
9273 /* Step 2 : update control buffer value for target address */
9274 hi3c->pXferData->CtrlBuf.pBuffer[index + 1U] =
9275 (((uint32_t)hi3c->pCCCDesc[index / 2U].CCCBuf.Size - nb_define_bytes) |
9276 hi3c->pCCCDesc[index / 2U].Direction |
9277 ((uint32_t)hi3c->pCCCDesc[index / 2U].TargetAddr << I3C_CR_ADD_Pos) |
9278 LL_I3C_CONTROLLER_MTYPE_DIRECT | stop_condition);
9279 }
9280
9281 /* Update control buffer value for the last CCC command */
9282 hi3c->pXferData->CtrlBuf.pBuffer[index] = (nb_define_bytes |
9283 ((uint32_t)hi3c->pCCCDesc[index / 2U].CCC << I3C_CR_CCC_Pos) |
9284 LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_RESTART);
9285
9286 /* At the last device we should generate a stop condition */
9287 hi3c->pXferData->CtrlBuf.pBuffer[index + 1U] =
9288 (((uint32_t)hi3c->pCCCDesc[index / 2U].CCCBuf.Size - nb_define_bytes) |
9289 hi3c->pCCCDesc[index / 2U].Direction |
9290 ((uint32_t)hi3c->pCCCDesc[index / 2U].TargetAddr << I3C_CR_ADD_Pos) |
9291 LL_I3C_CONTROLLER_MTYPE_DIRECT | LL_I3C_GENERATE_STOP);
9292 }
9293 }
9294 else
9295 {
9296 /*------------------------------------------ Private I3C/I2C ---------------------------------------------------*/
9297 /* Check on the control buffer size */
9298 if (hi3c->pXferData->CtrlBuf.Size < (uint32_t)counter)
9299 {
9300 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9301 status = HAL_ERROR;
9302 }
9303 else
9304 {
9305 /* Set remaining control buffer data counter */
9306 hi3c->ControlXferCount = (uint32_t)counter;
9307
9308 /* For loop on the number of devices */
9309 for (index = 0U; index < ((uint32_t)counter - 1U); index++)
9310 {
9311 /* Check on transfer direction */
9312 if (hi3c->pPrivateDesc[index].Direction == HAL_I3C_DIRECTION_READ)
9313 {
9314 nb_data_bytes = hi3c->pPrivateDesc[index].RxBuf.Size;
9315 }
9316 else
9317 {
9318 nb_data_bytes = hi3c->pPrivateDesc[index].TxBuf.Size;
9319 }
9320
9321 /* Update control buffer value */
9322 hi3c->pXferData->CtrlBuf.pBuffer[index] =
9323 (nb_data_bytes | hi3c->pPrivateDesc[index].Direction |
9324 ((uint32_t)hi3c->pPrivateDesc[index].TargetAddr << I3C_CR_ADD_Pos) |
9325 (option & I3C_OPERATION_TYPE_MASK) | stop_condition);
9326 }
9327
9328 /* Check on transfer direction */
9329 if (hi3c->pPrivateDesc[index].Direction == HAL_I3C_DIRECTION_READ)
9330 {
9331 nb_data_bytes = hi3c->pPrivateDesc[index].RxBuf.Size;
9332 }
9333 else
9334 {
9335 nb_data_bytes = hi3c->pPrivateDesc[index].TxBuf.Size;
9336 }
9337
9338 /* At the last device we should generate a stop condition */
9339 hi3c->pXferData->CtrlBuf.pBuffer[index] =
9340 (nb_data_bytes | hi3c->pPrivateDesc[index].Direction |
9341 ((uint32_t)hi3c->pPrivateDesc[index].TargetAddr << I3C_CR_ADD_Pos) |
9342 (option & I3C_OPERATION_TYPE_MASK) | LL_I3C_GENERATE_STOP);
9343 }
9344 }
9345 }
9346
9347 return status;
9348 }
9349
9350 /**
9351 * @brief Check if target device is ready for communication.
9352 * @param hi3c : Pointer to a I3C_HandleTypeDef structure that contains
9353 * the configuration information for the specified I3C.
9354 * @param pDevice : [IN] Structure to define the device address and the device type.
9355 * @param trials : [IN] Number of trials
9356 * @param timeout : [IN] Timeout duration
9357 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
9358 */
I3C_Ctrl_IsDevice_Ready(I3C_HandleTypeDef * hi3c,const I3C_DeviceTypeDef * pDevice,uint32_t trials,uint32_t timeout)9359 static HAL_StatusTypeDef I3C_Ctrl_IsDevice_Ready(I3C_HandleTypeDef *hi3c,
9360 const I3C_DeviceTypeDef *pDevice,
9361 uint32_t trials,
9362 uint32_t timeout)
9363 {
9364 __IO uint32_t I3C_Trials = 0UL;
9365 __IO uint32_t exit_condition;
9366 uint32_t CR_tmp;
9367 uint32_t tickstart;
9368 HAL_StatusTypeDef status = HAL_OK;
9369 HAL_I3C_StateTypeDef handle_state;
9370 uint32_t arbitration_previous_state;
9371
9372 /* Get I3C handle state */
9373 handle_state = hi3c->State;
9374
9375 /* check on the Mode */
9376 if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
9377 {
9378 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
9379 status = HAL_ERROR;
9380 }
9381 /* check on the State */
9382 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
9383 {
9384 status = HAL_BUSY;
9385 }
9386 else
9387 {
9388 /* Set handle transfer parameters */
9389 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
9390 hi3c->State = HAL_I3C_STATE_BUSY;
9391
9392 /* Before modify the arbitration, get the current arbitration state */
9393 arbitration_previous_state = LL_I3C_IsEnabledArbitrationHeader(hi3c->Instance);
9394
9395 /* Disable arbitration header */
9396 LL_I3C_DisableArbitrationHeader(hi3c->Instance);
9397
9398 CR_tmp = (HAL_I3C_DIRECTION_WRITE |
9399 ((uint32_t)pDevice->Address << I3C_CR_ADD_Pos) |
9400 pDevice->MessageType | LL_I3C_GENERATE_STOP);
9401
9402 do
9403 {
9404 /* Initiate a start condition by writing in the CR register */
9405 WRITE_REG(hi3c->Instance->CR, CR_tmp);
9406
9407 /* Calculate exit_condition value based on Frame complete and error flags */
9408 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
9409
9410 tickstart = HAL_GetTick();
9411
9412 while (exit_condition == 0U)
9413 {
9414 if (timeout != HAL_MAX_DELAY)
9415 {
9416 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
9417 {
9418 /* Update I3C error code */
9419 hi3c->ErrorCode |= HAL_I3C_ERROR_TIMEOUT;
9420 status = HAL_TIMEOUT;
9421
9422 break;
9423 }
9424 }
9425 /* Calculate exit_condition value based on Frame complete and error flags */
9426 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
9427 }
9428
9429 if (status == HAL_OK)
9430 {
9431 /* Check if the FCF flag has been set */
9432 if (__HAL_I3C_GET_FLAG(hi3c, I3C_EVR_FCF) == SET)
9433 {
9434 /* Clear frame complete flag */
9435 LL_I3C_ClearFlag_FC(hi3c->Instance);
9436
9437 /* Device is ready */
9438 break;
9439 }
9440 else
9441 {
9442 /* Clear ERR flag */
9443 LL_I3C_ClearFlag_ERR(hi3c->Instance);
9444 }
9445 }
9446
9447 /* Increment Trials */
9448 I3C_Trials++;
9449
9450 } while ((I3C_Trials < trials) && (status == HAL_OK));
9451
9452 /* Device is not ready */
9453 if (trials == I3C_Trials)
9454 {
9455 hi3c->ErrorCode = HAL_I3C_ERROR_ADDRESS_NACK;
9456 status = HAL_ERROR;
9457 }
9458
9459 /* update state to Previous state */
9460 I3C_StateUpdate(hi3c);
9461
9462 /* Check if previous arbitration state is enabled */
9463 if (arbitration_previous_state == 1U)
9464 {
9465 LL_I3C_EnableArbitrationHeader(hi3c->Instance);
9466 }
9467 }
9468
9469 return status;
9470 }
9471
9472 /**
9473 * @brief Manage the enabling of Interrupts.
9474 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9475 * information for the specified I3C.
9476 * @param InterruptRequest : [IN] Value of the interrupt request
9477 * @retval None
9478 */
I3C_Enable_IRQ(I3C_HandleTypeDef * hi3c,uint32_t InterruptRequest)9479 static void I3C_Enable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest)
9480 {
9481 uint32_t tmpisr = 0U;
9482
9483 /* Check if requested interrupts are related to listening mode */
9484 if ((InterruptRequest & I3C_XFER_LISTEN_IT) != 0U)
9485 {
9486 tmpisr |= ((InterruptRequest & (~I3C_XFER_LISTEN_IT)) | HAL_I3C_IT_ERRIE);
9487 }
9488
9489 /* Check if requested interrupts are related to target transmit in IT mode */
9490 if ((InterruptRequest & I3C_XFER_TARGET_TX_IT) != 0U)
9491 {
9492 /* Enable frame complete, transmit FIFO not full and error interrupts */
9493 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9494 }
9495
9496 /* Check if requested interrupts are related to target receive in IT mode */
9497 if ((InterruptRequest & I3C_XFER_TARGET_RX_IT) != 0U)
9498 {
9499 /* Enable frame complete, receive FIFO not empty and error interrupts */
9500 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE) ;
9501 }
9502
9503 /* Check if requested interrupts are related to transmit/receive in DMA mode */
9504 if ((InterruptRequest & I3C_XFER_DMA) != 0U)
9505 {
9506 /* Enable frame complete and error interrupts */
9507 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_ERRIE);
9508 }
9509
9510 /* Check if requested interrupts are related to target hot join */
9511 if ((InterruptRequest & I3C_XFER_TARGET_HOTJOIN) != 0U)
9512 {
9513 /* Enable dynamic address update and error interrupts */
9514 tmpisr |= (HAL_I3C_IT_DAUPDIE | HAL_I3C_IT_ERRIE);
9515 }
9516
9517 /* Check if requested interrupts are related to target control role */
9518 if ((InterruptRequest & I3C_XFER_TARGET_CTRLROLE) != 0U)
9519 {
9520 /* Enable control role update and error interrupts */
9521 tmpisr |= (HAL_I3C_IT_CRUPDIE | HAL_I3C_IT_ERRIE);
9522 }
9523
9524 /* Check if requested interrupts are related to target in band interrupt */
9525 if ((InterruptRequest & I3C_XFER_TARGET_IBI) != 0U)
9526 {
9527 /* Enable IBI end and error interrupts */
9528 tmpisr |= (HAL_I3C_IT_IBIENDIE | HAL_I3C_IT_ERRIE);
9529 }
9530
9531 /* Check if requested interrupts are related to controller transmit in IT mode */
9532 if ((InterruptRequest & I3C_XFER_CONTROLLER_TX_IT) != 0U)
9533 {
9534 /* Enable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9535 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9536 }
9537
9538 /* Check if requested interrupts are related to controller receive in IT mode */
9539 if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_IT) != 0U)
9540 {
9541 /* Enable frame complete, control FIFO not full, receive FIFO not empty and error interrupts */
9542 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9543 }
9544
9545 /* Check if requested interrupts are related to controller transmit read or a broadcast CCC in IT mode */
9546 if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_CCC_IT) != 0U)
9547 {
9548 /* Enable frame complete, transmit FIFO not full, control FIFO not full,
9549 receive FIFO not empty and error interrupts */
9550 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9551 }
9552
9553 /* Check if requested interrupts are related to controller transmit broadcast ENTDAA CCC in IT mode */
9554 if ((InterruptRequest & I3C_XFER_CONTROLLER_DAA_IT) != 0U)
9555 {
9556 /* Enable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9557 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9558 }
9559
9560 /* Enable requested interrupts */
9561 __HAL_I3C_ENABLE_IT(hi3c, tmpisr);
9562 }
9563
9564 /**
9565 * @brief Manage the disabling of Interrupts.
9566 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9567 * information for the specified I3C.
9568 * @param InterruptRequest : [IN] Value of the interrupt request
9569 * @retval None
9570 */
I3C_Disable_IRQ(I3C_HandleTypeDef * hi3c,uint32_t InterruptRequest)9571 static void I3C_Disable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest)
9572 {
9573 uint32_t tmpisr = 0U;
9574
9575 /* Check if requested interrupts are related to listening mode */
9576 if ((InterruptRequest & I3C_XFER_LISTEN_IT) != 0U)
9577 {
9578 tmpisr |= ((InterruptRequest & (~I3C_XFER_LISTEN_IT)) | HAL_I3C_IT_ERRIE);
9579 }
9580
9581 /* Check if requested interrupts are related to target transmit mode */
9582 if ((InterruptRequest & I3C_XFER_TARGET_TX_IT) != 0U)
9583 {
9584 /* Disable frame complete, transmit FIFO not full and error interrupts */
9585 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9586 }
9587
9588 /* Check if requested interrupts are related to target receive mode */
9589 if ((InterruptRequest & I3C_XFER_TARGET_RX_IT) != 0U)
9590 {
9591 /* Disable frame complete, receive FIFO not empty and error interrupts */
9592 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9593 }
9594
9595 /* Check if requested interrupts are related to transmit/receive in DMA mode */
9596 if ((InterruptRequest & I3C_XFER_DMA) != 0U)
9597 {
9598 /* Disable frame complete and error interrupts */
9599 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_ERRIE);
9600 }
9601
9602 /* Check if requested interrupts are related to target hot join */
9603 if ((InterruptRequest & I3C_XFER_TARGET_HOTJOIN) != 0U)
9604 {
9605 /* Disable dynamic address update and error interrupts */
9606 tmpisr |= (HAL_I3C_IT_DAUPDIE | HAL_I3C_IT_ERRIE);
9607 }
9608
9609 /* Check if requested interrupts are related to target control role */
9610 if ((InterruptRequest & I3C_XFER_TARGET_CTRLROLE) != 0U)
9611 {
9612 /* Disable control role update and error interrupts */
9613 tmpisr |= (HAL_I3C_IT_CRUPDIE | HAL_I3C_IT_ERRIE);
9614 }
9615
9616 /* Check if requested interrupts are related to target in band interrupt */
9617 if ((InterruptRequest & I3C_XFER_TARGET_IBI) != 0U)
9618 {
9619 /* Disable IBI end and error interrupts */
9620 tmpisr |= (HAL_I3C_IT_IBIENDIE | HAL_I3C_IT_ERRIE);
9621 }
9622
9623 /* Check if requested interrupts are related to controller transmit in IT mode */
9624 if ((InterruptRequest & I3C_XFER_CONTROLLER_TX_IT) != 0U)
9625 {
9626 /* Disable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9627 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9628 }
9629
9630 /* Check if requested interrupts are related to controller transmit read or a broadcast CCC in IT mode */
9631 if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_CCC_IT) != 0U)
9632 {
9633 /* Disable frame complete, transmit FIFO not full, control FIFO not full,
9634 receive FIFO not empty and error interrupts */
9635 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9636 }
9637
9638 /* Check if requested interrupts are related to controller transmit broadcast ENTDAA CCC in IT mode */
9639 if ((InterruptRequest & I3C_XFER_CONTROLLER_DAA_IT) != 0U)
9640 {
9641 /* Disable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9642 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9643 }
9644
9645 /* Disable requested interrupts */
9646 __HAL_I3C_DISABLE_IT(hi3c, tmpisr);
9647 }
9648
9649 /**
9650 * @brief I3C error treatment.
9651 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9652 * information for the specified I3C.
9653 * @retval None
9654 */
I3C_ErrorTreatment(I3C_HandleTypeDef * hi3c)9655 static void I3C_ErrorTreatment(I3C_HandleTypeDef *hi3c)
9656 {
9657 HAL_I3C_StateTypeDef tmpstate = hi3c->State;
9658 uint32_t dmaabortongoing = 0U;
9659
9660 /* Check on the state */
9661 if (tmpstate == HAL_I3C_STATE_BUSY)
9662 {
9663 /* Update handle state parameter */
9664 I3C_StateUpdate(hi3c);
9665
9666 /* Disable all interrupts related to busy state */
9667 I3C_Disable_IRQ(hi3c, (I3C_XFER_TARGET_IBI | I3C_XFER_TARGET_HOTJOIN | I3C_XFER_TARGET_CTRLROLE));
9668 }
9669 else
9670 {
9671 /* Disable all interrupts related to busy Tx and Rx state */
9672 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
9673
9674 /* Reset Tx counter */
9675 hi3c->TxXferCount = 0U;
9676
9677 /* Reset Rx counter */
9678 hi3c->RxXferCount = 0U;
9679
9680 /* Reset Control counter */
9681 hi3c->ControlXferCount = 0U;
9682
9683 /* Reset Tx function pointer */
9684 hi3c->ptrTxFunc = NULL;
9685
9686 /* Reset Rx function pointer */
9687 hi3c->ptrRxFunc = NULL;
9688
9689 /* Reset Context pointer */
9690 hi3c->pXferData = NULL;
9691 hi3c->pCCCDesc = NULL;
9692 hi3c->pPrivateDesc = NULL;
9693
9694 /* Flush all FIFOs */
9695 /* Flush the content of Tx Fifo */
9696 LL_I3C_RequestTxFIFOFlush(hi3c->Instance);
9697
9698 /* Flush the content of Rx Fifo */
9699 LL_I3C_RequestRxFIFOFlush(hi3c->Instance);
9700
9701 /* Check on the I3C mode: Control and status FIFOs available only with controller mode */
9702 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
9703 {
9704 /* Flush the content of Control Fifo */
9705 LL_I3C_RequestControlFIFOFlush(hi3c->Instance);
9706
9707 /* Flush the content of Status Fifo */
9708 LL_I3C_RequestStatusFIFOFlush(hi3c->Instance);
9709 }
9710
9711 #if defined(HAL_DMA_MODULE_ENABLED)
9712 /* Abort control DMA transfer if any */
9713 if (hi3c->hdmacr != NULL)
9714 {
9715 /* Disable control DMA Request */
9716 LL_I3C_DisableDMAReq_Control(hi3c->Instance);
9717
9718 /* Check DMA state */
9719 if (HAL_DMA_GetState(hi3c->hdmacr) != HAL_DMA_STATE_READY)
9720 {
9721 /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback()
9722 at end of DMA abort procedure */
9723
9724 /* DMA abort on going */
9725 dmaabortongoing = 1U;
9726
9727 /* Abort control DMA */
9728 if (HAL_DMA_Abort_IT(hi3c->hdmacr) != HAL_OK)
9729 {
9730 /* Call Directly XferAbortCallback function in case of error */
9731 hi3c->hdmacr->XferAbortCallback(hi3c->hdmacr);
9732 }
9733 }
9734 }
9735
9736 /* Abort RX DMA transfer if any */
9737 if (hi3c->hdmarx != NULL)
9738 {
9739 /* Disable Rx DMA Request */
9740 LL_I3C_DisableDMAReq_RX(hi3c->Instance);
9741
9742 /* Check DMA state */
9743 if (HAL_DMA_GetState(hi3c->hdmarx) != HAL_DMA_STATE_READY)
9744 {
9745 /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback()
9746 at end of DMA abort procedure */
9747 hi3c->hdmarx->XferAbortCallback = I3C_DMAAbort;
9748
9749 /* DMA abort on going */
9750 dmaabortongoing = 1U;
9751
9752 /* Abort DMA RX */
9753 if (HAL_DMA_Abort_IT(hi3c->hdmarx) != HAL_OK)
9754 {
9755 /* Call Directly XferAbortCallback function in case of error */
9756 hi3c->hdmarx->XferAbortCallback(hi3c->hdmarx);
9757 }
9758 }
9759 }
9760
9761 /* Abort TX DMA transfer if any */
9762 if (hi3c->hdmatx != NULL)
9763 {
9764 /* Disable Tx DMA Request */
9765 LL_I3C_DisableDMAReq_TX(hi3c->Instance);
9766
9767 /* Check DMA state */
9768 if (HAL_DMA_GetState(hi3c->hdmatx) != HAL_DMA_STATE_READY)
9769 {
9770 /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback()
9771 at end of DMA abort procedure */
9772 hi3c->hdmatx->XferAbortCallback = I3C_DMAAbort;
9773
9774 /* DMA abort on going */
9775 dmaabortongoing = 1U;
9776
9777 /* Abort DMA TX */
9778 if (HAL_DMA_Abort_IT(hi3c->hdmatx) != HAL_OK)
9779 {
9780 /* Call Directly XferAbortCallback function in case of error */
9781 hi3c->hdmatx->XferAbortCallback(hi3c->hdmatx);
9782 }
9783 }
9784 }
9785 #endif /* HAL_DMA_MODULE_ENABLED */
9786 }
9787
9788 /* Call Error callback if there is no DMA abort on going */
9789 if (dmaabortongoing == 0U)
9790 {
9791 I3C_TreatErrorCallback(hi3c);
9792 }
9793 }
9794
9795 /**
9796 * @brief I3C Error callback treatment.
9797 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9798 * information for the specified I3C.
9799 * @retval None
9800 */
I3C_TreatErrorCallback(I3C_HandleTypeDef * hi3c)9801 static void I3C_TreatErrorCallback(I3C_HandleTypeDef *hi3c)
9802 {
9803 if (hi3c->State == HAL_I3C_STATE_ABORT)
9804 {
9805 /* Update handle state parameter */
9806 I3C_StateUpdate(hi3c);
9807
9808 /* Call the corresponding callback to inform upper layer of End of Transfer */
9809 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1)
9810 hi3c->AbortCpltCallback(hi3c);
9811 #else
9812 HAL_I3C_AbortCpltCallback(hi3c);
9813 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
9814 }
9815 else
9816 {
9817 /* Update handle state parameter */
9818 I3C_StateUpdate(hi3c);
9819
9820 /* Call the corresponding callback to inform upper layer of End of Transfer */
9821 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1)
9822 hi3c->ErrorCallback(hi3c);
9823 #else
9824 HAL_I3C_ErrorCallback(hi3c);
9825 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
9826 }
9827 }
9828
9829 /**
9830 * @}
9831 */
9832
9833 #endif /* HAL_I3C_MODULE_ENABLED */
9834
9835 /**
9836 * @}
9837 */
9838
9839 /**
9840 * @}
9841 */
9842