1 /**
2 **********************************************************************************************************************
3 * @file stm32h7rsxx_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) 2022 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 an 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 "stm32h7rsxx_hal.h"
329
330 /** @addtogroup STM32H7RSxx_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 transfer descriptor
1665 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 descriptor.
2145 * @note This function must be called before initiate any communication transfer. This function help the preparation
2146 * of the full transfer usecase in a transfer descriptor which contained different buffer pointers
2147 * 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 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
5499 * @param timeout : [IN] Timeout duration in millisecond.
5500 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5501 */
HAL_I3C_Tgt_Transmit(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)5502 HAL_StatusTypeDef HAL_I3C_Tgt_Transmit(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout)
5503 {
5504 uint32_t tickstart;
5505 HAL_StatusTypeDef status = HAL_OK;
5506 HAL_I3C_StateTypeDef handle_state;
5507 uint32_t it_source;
5508
5509 /* check on the handle */
5510 if (hi3c == NULL)
5511 {
5512 status = HAL_ERROR;
5513 }
5514 else
5515 {
5516 /* Check the instance and the mode parameters */
5517 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5518 assert_param(IS_I3C_MODE(hi3c->Mode));
5519
5520 it_source = READ_REG(hi3c->Instance->IER);
5521
5522 /* Get I3C handle state */
5523 handle_state = hi3c->State;
5524
5525 /* Check on user parameters */
5526 if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U))
5527 {
5528 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5529 status = HAL_ERROR;
5530 }
5531 /* check on the Mode */
5532 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5533 {
5534 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5535 status = HAL_ERROR;
5536 }
5537 /* check on the State */
5538 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5539 {
5540 status = HAL_BUSY;
5541 }
5542 /* check if DEF or GRP CCC notifications are enabled */
5543 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5544 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5545 {
5546 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5547 status = HAL_ERROR;
5548 }
5549 /* Verify the dynamic address validity */
5550 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5551 {
5552 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5553 status = HAL_ERROR;
5554 }
5555 else
5556 {
5557 /* Set handle transfer parameters */
5558 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5559 hi3c->State = HAL_I3C_STATE_BUSY_TX;
5560 hi3c->pXferData = pXferData;
5561 hi3c->TxXferCount = pXferData->TxBuf.Size;
5562
5563 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
5564 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
5565 {
5566 /* Set byte treatment function pointer */
5567 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
5568 }
5569 else
5570 {
5571 /* Set word treatment function pointer */
5572 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
5573 }
5574
5575 /* Set Preload information */
5576 LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size);
5577
5578 /* Init tickstart for timeout management */
5579 tickstart = HAL_GetTick();
5580
5581 /* Do while until FC (Frame Complete) is set or timeout */
5582 do
5583 {
5584 /* Call transmit treatment function */
5585 hi3c->ptrTxFunc(hi3c);
5586
5587 /* Check for the Timeout */
5588 if (timeout != HAL_MAX_DELAY)
5589 {
5590 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
5591 {
5592 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
5593 status = HAL_TIMEOUT;
5594
5595 break;
5596 }
5597 }
5598 /* Exit loop on Frame complete or error flags */
5599 } while ((READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)) == 0U);
5600
5601 /* Clear frame complete flag */
5602 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
5603 {
5604 LL_I3C_ClearFlag_FC(hi3c->Instance);
5605 }
5606
5607 /* Check if all data bytes are transmitted */
5608 if ((LL_I3C_GetXferDataCount(hi3c->Instance) != hi3c->pXferData->TxBuf.Size) && (status == HAL_OK))
5609 {
5610 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
5611 status = HAL_ERROR;
5612 }
5613
5614 /* Check on error flag */
5615 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
5616 {
5617 /* Clear error flag */
5618 LL_I3C_ClearFlag_ERR(hi3c->Instance);
5619
5620 /* Update handle error code parameter */
5621 I3C_GetErrorSources(hi3c);
5622
5623 /* Update returned status value */
5624 status = HAL_ERROR;
5625 }
5626
5627 /* At the end of Tx process update state to Previous state */
5628 I3C_StateUpdate(hi3c);
5629 }
5630 }
5631
5632 return status;
5633 }
5634
5635 /**
5636 * @brief Target transmit private data in interrupt mode.
5637 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5638 * for the specified I3C.
5639 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
5640 * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data
5641 * to transmit in bytes (TxBuf.Size)).
5642 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
5643 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5644 */
HAL_I3C_Tgt_Transmit_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)5645 HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
5646 {
5647 HAL_I3C_StateTypeDef handle_state;
5648 HAL_StatusTypeDef status = HAL_OK;
5649 uint32_t it_source;
5650
5651 /* check on the handle */
5652 if (hi3c == NULL)
5653 {
5654 status = HAL_ERROR;
5655 }
5656 else
5657 {
5658 /* Check the instance and the mode parameters */
5659 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5660 assert_param(IS_I3C_MODE(hi3c->Mode));
5661
5662 it_source = READ_REG(hi3c->Instance->IER);
5663
5664 /* Get I3C handle state */
5665 handle_state = hi3c->State;
5666
5667 /* Check on user parameters */
5668 if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U))
5669 {
5670 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5671 status = HAL_ERROR;
5672 }
5673 /* check on the Mode */
5674 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5675 {
5676 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5677 status = HAL_ERROR;
5678 }
5679 /* check on the State */
5680 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5681 {
5682 status = HAL_BUSY;
5683 }
5684 /* check if DEF and GRP CCC notifications are enabled */
5685 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5686 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5687 {
5688 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5689 status = HAL_ERROR;
5690 }
5691 /* Verify the dynamic address validity */
5692 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5693 {
5694 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5695
5696 status = HAL_ERROR;
5697 }
5698 else
5699 {
5700 /* Set handle transfer parameters */
5701 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5702 hi3c->State = HAL_I3C_STATE_BUSY_TX;
5703 hi3c->pXferData = pXferData;
5704 hi3c->TxXferCount = pXferData->TxBuf.Size;
5705 hi3c->XferISR = I3C_Tgt_Tx_ISR;
5706
5707 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
5708 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
5709 {
5710 /* Set byte treatment function pointer */
5711 hi3c->ptrTxFunc = &I3C_TransmitByteTreatment;
5712 }
5713 else
5714 {
5715 /* Set word treatment function pointer */
5716 hi3c->ptrTxFunc = &I3C_TransmitWordTreatment;
5717 }
5718
5719 /* Set Preload information */
5720 LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size);
5721
5722 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
5723 of I3C interrupt handle execution before current process unlock */
5724
5725 /* Enable Tx process interrupts */
5726 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_TX_IT);
5727 }
5728 }
5729
5730 return status;
5731 }
5732
5733 #if defined(HAL_DMA_MODULE_ENABLED)
5734 /**
5735 * @brief Target transmit private data in DMA mode.
5736 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5737 * for the specified I3C.
5738 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers
5739 * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data
5740 * to transmit in bytes (TxBuf.Size)).
5741 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
5742 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5743 */
HAL_I3C_Tgt_Transmit_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)5744 HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
5745 {
5746 HAL_StatusTypeDef tx_dma_status;
5747 HAL_I3C_StateTypeDef handle_state;
5748 HAL_StatusTypeDef status = HAL_OK;
5749 uint32_t size_align_word;
5750 uint32_t it_source;
5751
5752 /* check on the handle */
5753 if (hi3c == NULL)
5754 {
5755 status = HAL_ERROR;
5756 }
5757 else
5758 {
5759 /* Check the instance and the mode parameters */
5760 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5761 assert_param(IS_I3C_MODE(hi3c->Mode));
5762
5763 it_source = READ_REG(hi3c->Instance->IER);
5764
5765 /* Get I3C handle state */
5766 handle_state = hi3c->State;
5767
5768 /* Check on user parameters */
5769 if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U))
5770 {
5771 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5772 status = HAL_ERROR;
5773 }
5774 /* Check on hdmatx handle */
5775 else if (hi3c->hdmatx == NULL)
5776 {
5777 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
5778 status = HAL_ERROR;
5779 }
5780 /* check on the Mode */
5781 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5782 {
5783 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5784 status = HAL_ERROR;
5785 }
5786 /* check on the State */
5787 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5788 {
5789 status = HAL_BUSY;
5790 }
5791 /* check if DEF and GRP CCC notifications are enabled */
5792 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5793 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5794 {
5795 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5796 status = HAL_ERROR;
5797 }
5798 /* Verify the dynamic address validity */
5799 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5800 {
5801 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5802 status = HAL_ERROR;
5803 }
5804 else
5805 {
5806 /* Set handle transfer parameters */
5807 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5808 hi3c->State = HAL_I3C_STATE_BUSY_TX;
5809 hi3c->pXferData = pXferData;
5810 hi3c->TxXferCount = pXferData->TxBuf.Size;
5811 hi3c->XferISR = I3C_Tgt_Tx_DMA_ISR;
5812
5813 /* Set Preload information */
5814 LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size);
5815
5816 /*------------------------------------ I3C DMA channel for the Tx Data -----------------------------------------*/
5817 /* Set the I3C DMA transfer complete callback */
5818 hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt;
5819
5820 /* Set the DMA error callback */
5821 hi3c->hdmatx->XferErrorCallback = I3C_DMAError;
5822
5823 /* Set the unused DMA callbacks to NULL */
5824 hi3c->hdmatx->XferHalfCpltCallback = NULL;
5825 hi3c->hdmatx->XferAbortCallback = NULL;
5826
5827 /* Check on the Tx threshold to know the Tx treatment process : byte or word */
5828 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4)
5829 {
5830 /* assert that DMA source and destination width are configured in byte */
5831 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
5832 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth));
5833
5834 /* Enable the Tx data DMA channel */
5835 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
5836 (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size);
5837 }
5838 else
5839 {
5840 /* assert that DMA source and destination width are configured in word */
5841 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth));
5842 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth));
5843
5844 /* Check to align data size in words */
5845 if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U)
5846 {
5847 /* Keep the same size */
5848 size_align_word = hi3c->pXferData->TxBuf.Size;
5849 }
5850 else
5851 {
5852 /* Modify size to be multiple of 4 */
5853 size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U));
5854 }
5855
5856 /* Enable the Tx data DMA channel */
5857 tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer,
5858 (uint32_t)&hi3c->Instance->TDWR, size_align_word);
5859 }
5860
5861 /* Check if DMA process is well started */
5862 if (tx_dma_status == HAL_OK)
5863 {
5864 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
5865 of I3C interrupt handle execution before current process unlock */
5866
5867 /* Enable Tx process interrupts */
5868 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
5869
5870 /* Update the number of remaining data bytes */
5871 hi3c->TxXferCount = 0U;
5872
5873 /* Enable Tx data DMA Request */
5874 LL_I3C_EnableDMAReq_TX(hi3c->Instance);
5875 }
5876 else
5877 {
5878 /* Set callback to NULL if DMA started */
5879 hi3c->hdmatx->XferCpltCallback = NULL;
5880 hi3c->hdmatx->XferErrorCallback = NULL;
5881
5882 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
5883 status = HAL_ERROR;
5884
5885 /* Update handle state parameter */
5886 I3C_StateUpdate(hi3c);
5887 }
5888 }
5889 }
5890
5891 return status;
5892 }
5893 #endif /* HAL_DMA_MODULE_ENABLED */
5894
5895 /**
5896 * @brief Target receive private data in polling mode.
5897 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
5898 * for the specified I3C.
5899 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
5900 * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data
5901 * to be received in bytes (RxBuf.Size)).
5902 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
5903 * @param timeout : [IN] Timeout duration in millisecond.
5904 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
5905 */
HAL_I3C_Tgt_Receive(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData,uint32_t timeout)5906 HAL_StatusTypeDef HAL_I3C_Tgt_Receive(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout)
5907 {
5908 uint32_t tickstart;
5909 HAL_StatusTypeDef status = HAL_OK;
5910 HAL_I3C_StateTypeDef handle_state;
5911 uint32_t it_source;
5912
5913 /* check on the handle */
5914 if (hi3c == NULL)
5915 {
5916 status = HAL_ERROR;
5917 }
5918 else
5919 {
5920 /* Check the instance and the mode parameters */
5921 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
5922 assert_param(IS_I3C_MODE(hi3c->Mode));
5923
5924 it_source = READ_REG(hi3c->Instance->IER);
5925
5926 /* Get I3C handle state */
5927 handle_state = hi3c->State;
5928
5929 /* Check on user parameters */
5930 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U))
5931 {
5932 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
5933 status = HAL_ERROR;
5934 }
5935 /* check on the Mode */
5936 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
5937 {
5938 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5939 status = HAL_ERROR;
5940 }
5941 /* check on the State */
5942 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
5943 {
5944 status = HAL_BUSY;
5945 }
5946 /* check if DEF and GRP CCC notifications are enabled */
5947 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
5948 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
5949 {
5950 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5951 status = HAL_ERROR;
5952 }
5953 /* Verify the dynamic address validity */
5954 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
5955 {
5956 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
5957 status = HAL_ERROR;
5958 }
5959 else
5960 {
5961 /* Set handle transfer parameters */
5962 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
5963 hi3c->State = HAL_I3C_STATE_BUSY_RX;
5964 hi3c->pXferData = pXferData;
5965 hi3c->RxXferCount = pXferData->RxBuf.Size;
5966
5967 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
5968 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
5969 {
5970 /* Set byte treatment function pointer */
5971 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
5972 }
5973 else
5974 {
5975 /* Set word treatment function pointer */
5976 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
5977 }
5978
5979 /* Init tickstart for timeout management */
5980 tickstart = HAL_GetTick();
5981
5982 /* Do while until FC (Frame Complete) is set or timeout */
5983 do
5984 {
5985 if (hi3c->RxXferCount > 0U)
5986 {
5987 /* Call receive treatment function */
5988 hi3c->ptrRxFunc(hi3c);
5989 }
5990
5991 /* Check for the Timeout */
5992 if (timeout != HAL_MAX_DELAY)
5993 {
5994 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
5995 {
5996 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
5997 status = HAL_TIMEOUT;
5998
5999 break;
6000 }
6001 }
6002 /* Exit loop on Frame complete or error flags */
6003 } while ((READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)) == 0U);
6004
6005 /* Clear frame complete flag */
6006 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET)
6007 {
6008 LL_I3C_ClearFlag_FC(hi3c->Instance);
6009 }
6010
6011 /* Check if all data bytes are received */
6012 if ((LL_I3C_GetXferDataCount(hi3c->Instance) != hi3c->pXferData->RxBuf.Size) && (status == HAL_OK))
6013 {
6014 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
6015 status = HAL_ERROR;
6016 }
6017
6018 /* Check on error flag */
6019 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6020 {
6021 /* Clear error flag */
6022 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6023
6024 /* Update handle error code parameter */
6025 I3C_GetErrorSources(hi3c);
6026
6027 status = HAL_ERROR;
6028 }
6029
6030 /* At the end of Rx process update state to previous state */
6031 I3C_StateUpdate(hi3c);
6032 }
6033 }
6034
6035 return status;
6036 }
6037
6038 /**
6039 * @brief Target receive private data in interrupt mode.
6040 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6041 * for the specified I3C.
6042 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
6043 * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data
6044 * to be received in bytes (RxBuf.Size)).
6045 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
6046 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6047 */
HAL_I3C_Tgt_Receive_IT(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)6048 HAL_StatusTypeDef HAL_I3C_Tgt_Receive_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
6049 {
6050 HAL_I3C_StateTypeDef handle_state;
6051 HAL_StatusTypeDef status = HAL_OK;
6052 uint32_t it_source;
6053
6054 /* check on the handle */
6055 if (hi3c == NULL)
6056 {
6057 status = HAL_ERROR;
6058 }
6059 else
6060 {
6061 /* Check the instance and the mode parameters */
6062 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6063 assert_param(IS_I3C_MODE(hi3c->Mode));
6064
6065 it_source = READ_REG(hi3c->Instance->IER);
6066
6067 /* Get I3C handle state */
6068 handle_state = hi3c->State;
6069
6070 /* Check on user parameters */
6071 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U))
6072 {
6073 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6074 status = HAL_ERROR;
6075 }
6076 /* check on the Mode */
6077 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6078 {
6079 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6080 status = HAL_ERROR;
6081 }
6082 /* check on the State */
6083 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6084 {
6085 status = HAL_BUSY;
6086 }
6087 /* check if DEF and GRP CCC notifications are enabled */
6088 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
6089 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
6090 {
6091 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6092 status = HAL_ERROR;
6093 }
6094 /* Verify the dynamic address validity */
6095 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6096 {
6097 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6098 status = HAL_ERROR;
6099 }
6100 else
6101 {
6102 /* Set handle transfer parameters */
6103 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6104 hi3c->State = HAL_I3C_STATE_BUSY_RX;
6105 hi3c->pXferData = pXferData;
6106 hi3c->RxXferCount = pXferData->RxBuf.Size;
6107 hi3c->XferISR = I3C_Tgt_Rx_ISR;
6108
6109 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
6110 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
6111 {
6112 /* Set byte treatment function pointer */
6113 hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment;
6114 }
6115 else
6116 {
6117 /* Set word treatment function pointer */
6118 hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment;
6119 }
6120
6121 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
6122 of I3C interrupt handle execution before current process unlock */
6123
6124 /* Enable Rx process interrupts */
6125 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT);
6126 }
6127 }
6128
6129 return status;
6130 }
6131
6132 #if defined(HAL_DMA_MODULE_ENABLED)
6133 /**
6134 * @brief Target receive private data in DMA mode.
6135 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6136 * for the specified I3C.
6137 * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers
6138 * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data
6139 * to be received in bytes (RxBuf.Size)).
6140 * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame().
6141 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6142 */
HAL_I3C_Tgt_Receive_DMA(I3C_HandleTypeDef * hi3c,I3C_XferTypeDef * pXferData)6143 HAL_StatusTypeDef HAL_I3C_Tgt_Receive_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData)
6144 {
6145 HAL_StatusTypeDef rx_dma_status;
6146 HAL_I3C_StateTypeDef handle_state;
6147 HAL_StatusTypeDef status = HAL_OK;
6148 uint32_t size_align_word;
6149 uint32_t it_source;
6150
6151 /* check on the handle */
6152 if (hi3c == NULL)
6153 {
6154 status = HAL_ERROR;
6155 }
6156 else
6157 {
6158 /* Check the instance and the mode parameters */
6159 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6160 assert_param(IS_I3C_MODE(hi3c->Mode));
6161
6162 it_source = READ_REG(hi3c->Instance->IER);
6163
6164 /* Get I3C handle state */
6165 handle_state = hi3c->State;
6166
6167 /* Check on user parameters */
6168 if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U))
6169 {
6170 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6171 status = HAL_ERROR;
6172 }
6173 /* Check on hdmarx handle */
6174 else if (hi3c->hdmarx == NULL)
6175 {
6176 hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM;
6177 status = HAL_ERROR;
6178
6179 /* Update handle state parameter */
6180 I3C_StateUpdate(hi3c);
6181 }
6182 /* check on the Mode */
6183 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6184 {
6185 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6186 status = HAL_ERROR;
6187 }
6188 /* check on the State */
6189 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6190 {
6191 status = HAL_BUSY;
6192 }
6193 /* check if DEF and GRP CCC notifications are enabled */
6194 else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) ||
6195 (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET))
6196 {
6197 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6198 status = HAL_ERROR;
6199 }
6200 /* Verify the dynamic address validity */
6201 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6202 {
6203 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6204 status = HAL_ERROR;
6205 }
6206 else
6207 {
6208 /* Set handle transfer parameters */
6209 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6210 hi3c->State = HAL_I3C_STATE_BUSY_RX;
6211 hi3c->pXferData = pXferData;
6212 hi3c->RxXferCount = pXferData->RxBuf.Size;
6213 hi3c->XferISR = I3C_Tgt_Rx_DMA_ISR;
6214
6215 /*------------------------------------ I3C DMA channel for the Rx Data ---------------------------------------*/
6216 /* Set the I3C DMA transfer complete callback */
6217 hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt;
6218
6219 /* Set the DMA error callback */
6220 hi3c->hdmarx->XferErrorCallback = I3C_DMAError;
6221
6222 /* Set the unused DMA callbacks to NULL */
6223 hi3c->hdmarx->XferHalfCpltCallback = NULL;
6224 hi3c->hdmarx->XferAbortCallback = NULL;
6225
6226 /* Check on the Rx threshold to know the Rx treatment process : byte or word */
6227 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
6228 {
6229 /* assert that DMA source and destination width are configured in byte */
6230 assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
6231 assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth));
6232
6233 /* Enable the Rx data DMA channel */
6234 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR,
6235 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size);
6236 }
6237 else
6238 {
6239 /* assert that DMA source and destination width are configured in word */
6240 assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth));
6241 assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth));
6242
6243 /* Check to align data size in words */
6244 if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U)
6245 {
6246 /* Keep the same size */
6247 size_align_word = hi3c->pXferData->RxBuf.Size;
6248 }
6249 else
6250 {
6251 /* Modify size to be multiple of 4 */
6252 size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U));
6253 }
6254
6255 /* Enable the Rx data DMA channel */
6256 rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR,
6257 (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word);
6258 }
6259
6260 if (rx_dma_status == HAL_OK)
6261 {
6262 /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk
6263 of I3C interrupt handle execution before current process unlock */
6264
6265 /* Enable Rx process interrupts */
6266 I3C_Enable_IRQ(hi3c, I3C_XFER_DMA);
6267
6268 /* Update the number of remaining data bytes */
6269 hi3c->RxXferCount = 0U;
6270
6271 /* Enable Rx data DMA Request */
6272 LL_I3C_EnableDMAReq_RX(hi3c->Instance);
6273 }
6274 else
6275 {
6276 /* Set callback to NULL if DMA started */
6277 hi3c->hdmarx->XferCpltCallback = NULL;
6278 hi3c->hdmarx->XferErrorCallback = NULL;
6279
6280 hi3c->ErrorCode = HAL_I3C_ERROR_DMA;
6281 status = HAL_ERROR;
6282
6283 /* Update handle state parameter */
6284 I3C_StateUpdate(hi3c);
6285 }
6286 }
6287 }
6288
6289 return status;
6290 }
6291 #endif /* HAL_DMA_MODULE_ENABLED */
6292
6293 /**
6294 * @brief Target send control role request in polling mode.
6295 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6296 * for the specified I3C.
6297 * @param timeout : [IN] Timeout duration in millisecond.
6298 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6299 */
HAL_I3C_Tgt_ControlRoleReq(I3C_HandleTypeDef * hi3c,uint32_t timeout)6300 HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq(I3C_HandleTypeDef *hi3c, uint32_t timeout)
6301 {
6302 uint32_t tickstart;
6303 HAL_I3C_StateTypeDef handle_state;
6304 HAL_StatusTypeDef status = HAL_OK;
6305
6306 /* check on the handle */
6307 if (hi3c == NULL)
6308 {
6309 status = HAL_ERROR;
6310 }
6311 else
6312 {
6313 /* Check the instance and the mode parameters */
6314 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6315 assert_param(IS_I3C_MODE(hi3c->Mode));
6316
6317 /* Get I3C handle state */
6318 handle_state = hi3c->State;
6319
6320 /* check on the Mode */
6321 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6322 {
6323 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6324 status = HAL_ERROR;
6325 }
6326 /* check on the State */
6327 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6328 {
6329 status = HAL_BUSY;
6330 }
6331 /* Verify the dynamic address validity */
6332 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6333 {
6334 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6335 status = HAL_ERROR;
6336 }
6337 else
6338 {
6339 /* Verify if control role request feature is enabled */
6340 if (LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance) != 1U)
6341 {
6342 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6343 status = HAL_ERROR;
6344 }
6345 }
6346
6347 if (status == HAL_OK)
6348 {
6349 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6350 hi3c->State = HAL_I3C_STATE_BUSY;
6351
6352 /* Init tickstart for timeout management */
6353 tickstart = HAL_GetTick();
6354
6355 /* Request Controllership */
6356 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ, 0U);
6357
6358 /* Wait Controllership completion confirmation flag */
6359 status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_CRUPDF, RESET, timeout, tickstart);
6360
6361 /* Clear Control role request flag */
6362 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_CRUPDF) == SET)
6363 {
6364 LL_I3C_ClearFlag_CRUPD(hi3c->Instance);
6365 }
6366
6367 /* Check on error flag */
6368 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6369 {
6370 /* Clear error flag */
6371 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6372
6373 /* Update handle error code parameter */
6374 I3C_GetErrorSources(hi3c);
6375
6376 /* Update handle state parameter to previous state */
6377 I3C_StateUpdate(hi3c);
6378
6379 status = HAL_ERROR;
6380 }
6381 else
6382 {
6383 /* Update handle state parameter to previous state */
6384 I3C_StateUpdate(hi3c);
6385 }
6386 }
6387 }
6388
6389 return status;
6390 }
6391
6392 /**
6393 * @brief Target send control role request in interrupt mode.
6394 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
6395 * for the specified I3C.
6396 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6397 */
HAL_I3C_Tgt_ControlRoleReq_IT(I3C_HandleTypeDef * hi3c)6398 HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq_IT(I3C_HandleTypeDef *hi3c)
6399 {
6400 HAL_I3C_StateTypeDef handle_state;
6401 HAL_StatusTypeDef status = HAL_OK;
6402
6403 /* check on the handle */
6404 if (hi3c == NULL)
6405 {
6406 status = HAL_ERROR;
6407 }
6408 else
6409 {
6410 /* Check the instance and the mode parameters */
6411 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6412 assert_param(IS_I3C_MODE(hi3c->Mode));
6413
6414 /* Get I3C handle state */
6415 handle_state = hi3c->State;
6416
6417 /* Check on the Mode */
6418 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6419 {
6420 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6421 status = HAL_ERROR;
6422 }
6423 /* check on the State */
6424 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6425 {
6426 status = HAL_BUSY;
6427 }
6428 /* Verify the dynamic address validity */
6429 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6430 {
6431 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6432 status = HAL_ERROR;
6433 }
6434 else
6435 {
6436 /* Verify if control role request feature is enabled */
6437 if (LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance) != 1U)
6438 {
6439 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6440 status = HAL_ERROR;
6441 }
6442 }
6443
6444 if (status == HAL_OK)
6445 {
6446 /* Update handle parameters */
6447 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6448 hi3c->State = HAL_I3C_STATE_BUSY;
6449 hi3c->XferISR = I3C_Tgt_CtrlRole_ISR;
6450
6451 /* Enable controller-role update and error interrupts */
6452 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_CTRLROLE);
6453
6454 /* Request Controllership */
6455 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ, 0U);
6456 }
6457 }
6458
6459 return status;
6460 }
6461
6462 /**
6463 * @brief Target send hot join request in polling mode.
6464 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6465 * information for the specified I3C.
6466 * @param pAddress : [IN/OUT] Pointer to the target own dynamic address assigned by the controller.
6467 * @param timeout : [IN] Timeout duration in millisecond.
6468 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6469 */
HAL_I3C_Tgt_HotJoinReq(I3C_HandleTypeDef * hi3c,uint8_t * pAddress,uint32_t timeout)6470 HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq(I3C_HandleTypeDef *hi3c, uint8_t *pAddress, uint32_t timeout)
6471 {
6472 uint32_t tickstart;
6473 HAL_I3C_StateTypeDef handle_state;
6474 uint32_t valid_dynamic_address;
6475 HAL_StatusTypeDef status = HAL_OK;
6476
6477 /* check on the handle */
6478 if (hi3c == NULL)
6479 {
6480 status = HAL_ERROR;
6481 }
6482 else
6483 {
6484 /* Check the instance and the mode parameters */
6485 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6486 assert_param(IS_I3C_MODE(hi3c->Mode));
6487
6488 /* Get I3C handle state */
6489 handle_state = hi3c->State;
6490
6491 /* Check on the pAddress value */
6492 if (pAddress == NULL)
6493 {
6494 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6495 status = HAL_ERROR;
6496 }
6497 /* Check on the Mode */
6498 else if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6499 {
6500 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6501 status = HAL_ERROR;
6502 }
6503 /* check on the State */
6504 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6505 {
6506 status = HAL_BUSY;
6507 }
6508 else
6509 {
6510 /* Check on the hot join request feature */
6511 if (LL_I3C_IsEnabledHotJoin(hi3c->Instance) != 1U)
6512 {
6513 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6514 status = HAL_ERROR;
6515 }
6516 }
6517
6518 if (status == HAL_OK)
6519 {
6520 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6521 hi3c->State = HAL_I3C_STATE_BUSY;
6522
6523 /* Init tickstart for timeout management */
6524 tickstart = HAL_GetTick();
6525
6526 /* Request hot join */
6527 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_HOT_JOIN, 0U);
6528
6529 /* Wait hot join completion confirmation flag */
6530 status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_DAUPDF, RESET, timeout, tickstart);
6531
6532 /* Clear dynamic address update flag */
6533 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_DAUPDF) == SET)
6534 {
6535 LL_I3C_ClearFlag_DAUPD(hi3c->Instance);
6536 }
6537
6538 /* Get dynamic address validity flag */
6539 valid_dynamic_address = LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance);
6540
6541 /* Check the validity of the own dynamic address */
6542 if (valid_dynamic_address == 0U)
6543 {
6544 hi3c->ErrorCode = HAL_I3C_ERROR_DYNAMIC_ADDR;
6545 status = HAL_ERROR;
6546
6547 /* Update handle state parameter to previous state */
6548 I3C_StateUpdate(hi3c);
6549 }
6550 /* Check on error flag */
6551 else if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6552 {
6553 /* Clear error flag */
6554 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6555
6556 /* Update handle error code parameter */
6557 I3C_GetErrorSources(hi3c);
6558
6559 /* Update handle state parameter to previous state */
6560 I3C_StateUpdate(hi3c);
6561
6562 status = HAL_ERROR;
6563 }
6564 else
6565 {
6566 /* Update handle state parameter to previous state */
6567 I3C_StateUpdate(hi3c);
6568
6569 /* Get assigned dynamic address */
6570 *pAddress = LL_I3C_GetOwnDynamicAddress(hi3c->Instance);
6571 }
6572 }
6573 }
6574
6575 return status;
6576 }
6577
6578 /**
6579 * @brief Target send hot join request in interrupt mode.
6580 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6581 * information for the specified I3C.
6582 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6583 */
HAL_I3C_Tgt_HotJoinReq_IT(I3C_HandleTypeDef * hi3c)6584 HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq_IT(I3C_HandleTypeDef *hi3c)
6585 {
6586 HAL_I3C_StateTypeDef handle_state;
6587 HAL_StatusTypeDef status = HAL_OK;
6588
6589 /* check on the handle */
6590 if (hi3c == NULL)
6591 {
6592 status = HAL_ERROR;
6593 }
6594 else
6595 {
6596 /* Check the instance and the mode parameters */
6597 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6598 assert_param(IS_I3C_MODE(hi3c->Mode));
6599
6600 /* Get I3C handle state */
6601 handle_state = hi3c->State;
6602
6603 /* Check on the Mode */
6604 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6605 {
6606 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6607 status = HAL_ERROR;
6608 }
6609 /* check on the State */
6610 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6611 {
6612 status = HAL_BUSY;
6613 }
6614 /* Check on the hot join request feature */
6615 else if (LL_I3C_IsEnabledHotJoin(hi3c->Instance) != 1U)
6616 {
6617 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6618 status = HAL_ERROR;
6619 }
6620 else
6621 {
6622 /* Update handle parameters */
6623 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6624 hi3c->State = HAL_I3C_STATE_BUSY;
6625 hi3c->XferISR = I3C_Tgt_HotJoin_ISR;
6626
6627 /* Enable dynamic address update and error interrupts */
6628 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_HOTJOIN);
6629
6630 /* Request hot join */
6631 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_HOT_JOIN, 0U);
6632 }
6633 }
6634
6635 return status;
6636 }
6637
6638 /**
6639 * @brief Target send IBI request in polling mode.
6640 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6641 * information for the specified I3C.
6642 * @param pPayload : [IN] Pointer to the buffer contains the payload data.
6643 * @param payloadSize : [IN] Payload buffer size in bytes.
6644 * @param timeout : [IN] Timeout duration in millisecond.
6645 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6646 */
HAL_I3C_Tgt_IBIReq(I3C_HandleTypeDef * hi3c,const uint8_t * pPayload,uint8_t payloadSize,uint32_t timeout)6647 HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload,
6648 uint8_t payloadSize, uint32_t timeout)
6649 {
6650 uint32_t tickstart;
6651 uint32_t payload_value = 0U;
6652 HAL_I3C_StateTypeDef handle_state;
6653 HAL_StatusTypeDef status = HAL_OK;
6654
6655 /* check on the handle */
6656 if (hi3c == NULL)
6657 {
6658 status = HAL_ERROR;
6659 }
6660 else
6661 {
6662 /* Check the instance and the mode parameters */
6663 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6664 assert_param(IS_I3C_MODE(hi3c->Mode));
6665
6666 /* Get I3C handle state */
6667 handle_state = hi3c->State;
6668
6669 /* Check on the Mode */
6670 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6671 {
6672 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6673 status = HAL_ERROR;
6674 }
6675 /* check on the State */
6676 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6677 {
6678 status = HAL_BUSY;
6679 }
6680 /* Verify the dynamic address validity */
6681 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6682 {
6683 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6684 status = HAL_ERROR;
6685 }
6686 else
6687 {
6688 /* Verify if IBI request feature is enabled*/
6689 if ((LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U))
6690 {
6691 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6692 status = HAL_ERROR;
6693 }
6694 }
6695
6696 if (status == HAL_OK)
6697 {
6698 /* Update handle parameters */
6699 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6700 hi3c->State = HAL_I3C_STATE_BUSY;
6701
6702 /* Check on the IBI additional data */
6703 if (LL_I3C_GetDeviceIBIPayload(hi3c->Instance) == LL_I3C_IBI_ADDITIONAL_DATA)
6704 {
6705 /* Check on the pPayload and payloadSize values */
6706 if ((pPayload == NULL) || (payloadSize == 0U))
6707 {
6708 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6709 status = HAL_ERROR;
6710
6711 /* Update handle state parameter */
6712 I3C_StateUpdate(hi3c);
6713 }
6714 else
6715 {
6716 /* For loop to calculate the payload value */
6717 for (uint32_t index = 0U; index < payloadSize; index++)
6718 {
6719 payload_value |= ((uint32_t)pPayload[index] << (index * 8U));
6720 }
6721
6722 /* Load IBI payload data */
6723 LL_I3C_SetIBIPayload(hi3c->Instance, payload_value);
6724 }
6725 }
6726
6727 if (status == HAL_OK)
6728 {
6729 /* Init tickstart for timeout management */
6730 tickstart = HAL_GetTick();
6731
6732 /* Request IBI */
6733 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_IBI, payloadSize);
6734
6735 /* Wait IBI completion confirmation flag */
6736 status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_IBIENDF, RESET, timeout, tickstart);
6737
6738 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_IBIENDF) == SET)
6739 {
6740 /* Clear IBI end process flag */
6741 LL_I3C_ClearFlag_IBIEND(hi3c->Instance);
6742 }
6743
6744 /* Check on error flag value */
6745 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
6746 {
6747 /* Clear error flag */
6748 LL_I3C_ClearFlag_ERR(hi3c->Instance);
6749
6750 /* Update handle error code parameter */
6751 I3C_GetErrorSources(hi3c);
6752
6753 /* Update handle state parameter to previous state */
6754 I3C_StateUpdate(hi3c);
6755
6756 status = HAL_ERROR;
6757 }
6758 else
6759 {
6760 /* Update handle state parameter to previous state */
6761 I3C_StateUpdate(hi3c);
6762 }
6763 }
6764 }
6765 }
6766
6767 return status;
6768 }
6769
6770 /**
6771 * @brief Target send IBI request in interrupt mode.
6772 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6773 * information for the specified I3C.
6774 * @param pPayload : [IN] Pointer to the buffer contains the payload data.
6775 * @param payloadSize : [IN] Payload buffer size in bytes.
6776 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6777 */
HAL_I3C_Tgt_IBIReq_IT(I3C_HandleTypeDef * hi3c,const uint8_t * pPayload,uint8_t payloadSize)6778 HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq_IT(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload, uint8_t payloadSize)
6779 {
6780 uint32_t payload_value = 0U;
6781 HAL_I3C_StateTypeDef handle_state;
6782 HAL_StatusTypeDef status = HAL_OK;
6783
6784 /* check on the handle */
6785 if (hi3c == NULL)
6786 {
6787 status = HAL_ERROR;
6788 }
6789 else
6790 {
6791 /* Check the instance and the mode parameters */
6792 assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance));
6793 assert_param(IS_I3C_MODE(hi3c->Mode));
6794
6795 /* Get I3C handle state */
6796 handle_state = hi3c->State;
6797
6798 /* Check on the Mode */
6799 if (hi3c->Mode != HAL_I3C_MODE_TARGET)
6800 {
6801 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6802 status = HAL_ERROR;
6803 }
6804 /* check on the State */
6805 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
6806 {
6807 status = HAL_BUSY;
6808 }
6809 /* Verify the dynamic address validity */
6810 else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U)
6811 {
6812 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6813 status = HAL_ERROR;
6814 }
6815 else
6816 {
6817 /* Verify if IBI request feature is enabled */
6818 if (LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U)
6819 {
6820 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
6821 status = HAL_ERROR;
6822 }
6823 }
6824
6825 if (status == HAL_OK)
6826 {
6827 /* Update handle parameters */
6828 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
6829 hi3c->State = HAL_I3C_STATE_BUSY;
6830 hi3c->XferISR = I3C_Tgt_IBI_ISR;
6831
6832 /* Check on the IBI additional data */
6833 if (LL_I3C_GetDeviceIBIPayload(hi3c->Instance) == LL_I3C_IBI_ADDITIONAL_DATA)
6834 {
6835 /* Check on the pPayload and payloadSize values */
6836 if ((pPayload == NULL) || (payloadSize == 0U))
6837 {
6838 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
6839 status = HAL_ERROR;
6840
6841 /* Update handle state parameter */
6842 I3C_StateUpdate(hi3c);
6843 }
6844 else
6845 {
6846 /* For loop to calculate the payload value */
6847 for (uint32_t index = 0U; index < payloadSize; index++)
6848 {
6849 payload_value |= ((uint32_t)pPayload[index] << (index * 8U));
6850 }
6851
6852 /* Load IBI payload data */
6853 LL_I3C_SetIBIPayload(hi3c->Instance, payload_value);
6854 }
6855 }
6856
6857 /* Enable IBI end and error interrupts */
6858 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_IBI);
6859
6860 /* Request IBI */
6861 LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_IBI, payloadSize);
6862 }
6863 }
6864
6865 return status;
6866 }
6867 /**
6868 * @}
6869 */
6870
6871 /** @defgroup I3C_Exported_Functions_Group7 Generic and Common functions.
6872 * @brief I3C generic and common functions.
6873 *
6874 @verbatim
6875 =======================================================================================================================
6876 ##### Generic and Common functions #####
6877 =======================================================================================================================
6878 [..] This subsection provides a set of functions allowing to Abort transfer or to get in run-time the status
6879 of the peripheral.
6880
6881 (+) Call the function HAL_I3C_Abort_IT() to abort the current transfer either in DMA or IT.
6882 (+) Call the function HAL_I3C_GetState() to get the I3C handle state.
6883 (+) Call the function HAL_I3C_GetMode() to get the I3C handle mode.
6884 (+) Call the function HAL_I3C_GetError() to get the error code.
6885 (+) Call the function HAL_I3C_Get_ENTDAA_Payload_Info() to get BCR, DCR and PID information after ENTDAA.
6886
6887 @endverbatim
6888 * @{
6889 */
6890
6891 /**
6892 * @brief Abort an I3C IT or DMA process communication with Interrupt.
6893 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6894 * information for the specified I3C.
6895 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
6896 */
HAL_I3C_Abort_IT(I3C_HandleTypeDef * hi3c)6897 HAL_StatusTypeDef HAL_I3C_Abort_IT(I3C_HandleTypeDef *hi3c)
6898 {
6899 HAL_StatusTypeDef status = HAL_OK;
6900
6901 /* check on the handle */
6902 if (hi3c == NULL)
6903 {
6904 status = HAL_ERROR;
6905 }
6906 else
6907 {
6908 if (hi3c->State != HAL_I3C_STATE_ABORT)
6909 {
6910 /* Set State at HAL_I3C_STATE_ABORT */
6911 hi3c->State = HAL_I3C_STATE_ABORT;
6912
6913 /* Disable Error Interrupts */
6914 __HAL_I3C_DISABLE_IT(hi3c, HAL_I3C_IT_ERRIE);
6915
6916 hi3c->XferISR = I3C_Abort_ISR;
6917
6918 /* Flush the different Fifos to generate an automatic stop mode link to underflow or overflow detection timeout */
6919 /* Flush the content of Tx Fifo */
6920 LL_I3C_RequestTxFIFOFlush(hi3c->Instance);
6921
6922 /* Flush the content of Rx Fifo */
6923 LL_I3C_RequestRxFIFOFlush(hi3c->Instance);
6924
6925 /* Check on the I3C mode: Control and status FIFOs available only with controller mode */
6926 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
6927 {
6928 /* Flush the content of Control Fifo */
6929 LL_I3C_RequestControlFIFOFlush(hi3c->Instance);
6930
6931 /* Flush the content of Status Fifo */
6932 LL_I3C_RequestStatusFIFOFlush(hi3c->Instance);
6933 }
6934
6935 /* Disable all DMA Requests */
6936 LL_I3C_DisableDMAReq_Control(hi3c->Instance);
6937 LL_I3C_DisableDMAReq_RX(hi3c->Instance);
6938 LL_I3C_DisableDMAReq_TX(hi3c->Instance);
6939 LL_I3C_DisableDMAReq_Status(hi3c->Instance);
6940
6941 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
6942 {
6943 /* Note : The I3C interrupts must be enabled after unlocking current process
6944 to avoid the risk of I3C interrupt handle execution before current
6945 process unlock */
6946 I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
6947 }
6948 else
6949 {
6950 /* Note : The I3C interrupts must be enabled after unlocking current process
6951 to avoid the risk of I3C interrupt handle execution before current
6952 process unlock */
6953 I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT);
6954 }
6955 }
6956 else
6957 {
6958 return HAL_BUSY;
6959 }
6960 }
6961
6962 return status;
6963 }
6964
6965 /**
6966 * @brief Return the I3C handle state.
6967 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6968 * information for the specified I3C.
6969 * @retval HAL State : [OUT] Value from HAL_I3C_StateTypeDef enumeration.
6970 */
HAL_I3C_GetState(const I3C_HandleTypeDef * hi3c)6971 HAL_I3C_StateTypeDef HAL_I3C_GetState(const I3C_HandleTypeDef *hi3c)
6972 {
6973 return hi3c->State;
6974 }
6975
6976 /**
6977 * @brief Returns the I3C handle mode.
6978 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6979 * information for the specified I3C.
6980 * @retval HAL Mode : [OUT] Value from HAL_I3C_ModeTypeDef enumeration.
6981 */
HAL_I3C_GetMode(const I3C_HandleTypeDef * hi3c)6982 HAL_I3C_ModeTypeDef HAL_I3C_GetMode(const I3C_HandleTypeDef *hi3c)
6983 {
6984 return hi3c->Mode;
6985 }
6986
6987 /**
6988 * @brief Return the I3C error code.
6989 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
6990 * information for the specified I3C.
6991 * @retval I3C Error Code : [OUT] Value from @ref I3C_ERROR_CODE_DEFINITION.
6992 */
HAL_I3C_GetError(const I3C_HandleTypeDef * hi3c)6993 uint32_t HAL_I3C_GetError(const I3C_HandleTypeDef *hi3c)
6994 {
6995 return hi3c->ErrorCode;
6996 }
6997
6998 /**
6999 * @brief Target/Controller Get Common Command Code Information updated after event.
7000 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7001 * for the specified I3C.
7002 * @param notifyId : [IN] Parameter indicates which notification is signaled.
7003 * It can be a combination of value of @ref HAL_I3C_Notification_ID_definition.
7004 * @param pCCCInfo : [IN/OUT] Pointer to an I3C_CCCInfoTypeDef structure that contains the CCC information
7005 * updated after CCC event.
7006 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7007 */
HAL_I3C_GetCCCInfo(I3C_HandleTypeDef * hi3c,uint32_t notifyId,I3C_CCCInfoTypeDef * pCCCInfo)7008 HAL_StatusTypeDef HAL_I3C_GetCCCInfo(I3C_HandleTypeDef *hi3c,
7009 uint32_t notifyId,
7010 I3C_CCCInfoTypeDef *pCCCInfo)
7011 {
7012 HAL_StatusTypeDef status = HAL_OK;
7013
7014 /* check on the handle */
7015 if (hi3c == NULL)
7016 {
7017 status = HAL_ERROR;
7018 }
7019 else
7020 {
7021 /* Check on user parameters */
7022 if (pCCCInfo == NULL)
7023 {
7024 /* Update handle error code parameter */
7025 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
7026 status = HAL_ERROR;
7027 }
7028 /* Check the I3C state */
7029 else if (hi3c->State == HAL_I3C_STATE_RESET)
7030 {
7031 /* Update handle error code parameter */
7032 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
7033 status = HAL_ERROR;
7034 }
7035 else
7036 {
7037 /* Retrieve Target Dynamic Address value and Validity (target/controller) */
7038 if ((notifyId & EVENT_ID_DAU) == EVENT_ID_DAU)
7039 {
7040 pCCCInfo->DynamicAddrValid = LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance);
7041 pCCCInfo->DynamicAddr = LL_I3C_GetOwnDynamicAddress(hi3c->Instance);
7042 }
7043
7044 /* Retrieve Maximum Write Data Length (target) */
7045 if ((notifyId & EVENT_ID_SETMWL) == EVENT_ID_SETMWL)
7046 {
7047 pCCCInfo->MaxWriteLength = LL_I3C_GetMaxWriteLength(hi3c->Instance);
7048 }
7049
7050 /* Retrieve Maximum Read Data Length (target) */
7051 if ((notifyId & EVENT_ID_SETMRL) == EVENT_ID_SETMRL)
7052 {
7053 pCCCInfo->MaxReadLength = LL_I3C_GetMaxReadLength(hi3c->Instance);
7054 }
7055
7056 /* Retrieve Reset Action/Level on received reset pattern (target) */
7057 if ((notifyId & EVENT_ID_RSTACT) == EVENT_ID_RSTACT)
7058 {
7059 pCCCInfo->ResetAction = LL_I3C_GetResetAction(hi3c->Instance);
7060 }
7061
7062 /* Retrieve Activity State (target) */
7063 if ((notifyId & EVENT_ID_ENTASx) == EVENT_ID_ENTASx)
7064 {
7065 pCCCInfo->ActivityState = LL_I3C_GetActivityState(hi3c->Instance);
7066 }
7067
7068 /* Retrieve Interrupt allowed status (target) */
7069 if ((notifyId & EVENT_ID_ENEC_DISEC) == EVENT_ID_ENEC_DISEC)
7070 {
7071 pCCCInfo->HotJoinAllowed = LL_I3C_IsEnabledHotJoin(hi3c->Instance);
7072 pCCCInfo->InBandAllowed = LL_I3C_IsEnabledIBI(hi3c->Instance);
7073 pCCCInfo->CtrlRoleAllowed = LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance);
7074 }
7075
7076 /* Retrieve In Band Interrupt information (controller) */
7077 if ((notifyId & EVENT_ID_IBI) == EVENT_ID_IBI)
7078 {
7079 pCCCInfo->IBICRTgtAddr = LL_I3C_GetIBITargetAddr(hi3c->Instance);
7080 pCCCInfo->IBITgtNbPayload = LL_I3C_GetNbIBIAddData(hi3c->Instance);
7081 pCCCInfo->IBITgtPayload = LL_I3C_GetIBIPayload(hi3c->Instance);
7082 }
7083
7084 /* Retrieve Controller role request Interrupt information (controller) */
7085 if ((notifyId & EVENT_ID_CR) == EVENT_ID_CR)
7086 {
7087 pCCCInfo->IBICRTgtAddr = LL_I3C_GetIBITargetAddr(hi3c->Instance);
7088 }
7089 }
7090 }
7091
7092 return status;
7093 }
7094
7095 /**
7096 * @brief Get BCR, DCR and PID information after ENTDAA.
7097 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7098 * for the specified I3C.
7099 * @param ENTDAA_payload :[IN] Payload received after ENTDAA
7100 * @param pENTDAA_payload :[OUT] Pointer to an I3C_ENTDAAPayloadTypeDef structure that contains the BCR, DCR and PID
7101 * information.
7102 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7103 */
HAL_I3C_Get_ENTDAA_Payload_Info(I3C_HandleTypeDef * hi3c,uint64_t ENTDAA_payload,I3C_ENTDAAPayloadTypeDef * pENTDAA_payload)7104 HAL_StatusTypeDef HAL_I3C_Get_ENTDAA_Payload_Info(I3C_HandleTypeDef *hi3c,
7105 uint64_t ENTDAA_payload,
7106 I3C_ENTDAAPayloadTypeDef *pENTDAA_payload)
7107 {
7108 HAL_StatusTypeDef status = HAL_OK;
7109 uint32_t BCR;
7110 uint64_t PID;
7111
7112 /* check on the handle */
7113 if (hi3c == NULL)
7114 {
7115 status = HAL_ERROR;
7116 }
7117 else
7118 {
7119 /* Check on user parameters */
7120 if (pENTDAA_payload == NULL)
7121 {
7122 /* Update handle error code parameter */
7123 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
7124 status = HAL_ERROR;
7125 }
7126 else
7127 {
7128 /* Get Bus Characterics */
7129 BCR = __HAL_I3C_GET_BCR(ENTDAA_payload);
7130
7131 /* Retrieve BCR information */
7132 pENTDAA_payload->BCR.IBIPayload = __HAL_I3C_GET_IBI_PAYLOAD(BCR);
7133 pENTDAA_payload->BCR.IBIRequestCapable = __HAL_I3C_GET_IBI_CAPABLE(BCR);
7134 pENTDAA_payload->BCR.DeviceRole = __HAL_I3C_GET_CR_CAPABLE(BCR);
7135 pENTDAA_payload->BCR.AdvancedCapabilities = I3C_GET_ADVANCED_CAPABLE(BCR);
7136 pENTDAA_payload->BCR.OfflineCapable = I3C_GET_OFFLINE_CAPABLE(BCR);
7137 pENTDAA_payload->BCR.VirtualTargetSupport = I3C_GET_VIRTUAL_TGT(BCR);
7138 pENTDAA_payload->BCR.MaxDataSpeedLimitation = I3C_GET_MAX_DATA_SPEED_LIMIT(BCR);
7139
7140 /* Get Device Characterics */
7141 pENTDAA_payload->DCR = I3C_GET_DCR(ENTDAA_payload);
7142
7143 /* Get Provisioned ID */
7144 PID = I3C_GET_PID(ENTDAA_payload);
7145
7146 /* Change PID from BigEndian to litlleEndian */
7147 PID = (uint64_t)((((uint64_t)I3C_BIG_TO_LITTLE_ENDIAN((uint32_t) PID) << 32) |
7148 ((uint64_t)I3C_BIG_TO_LITTLE_ENDIAN((uint32_t)(PID >> 32)))) >> 16);
7149
7150 /* Retrieve PID information*/
7151 pENTDAA_payload->PID.MIPIMID = I3C_GET_MIPIMID(PID);
7152 pENTDAA_payload->PID.IDTSEL = I3C_GET_IDTSEL(PID);
7153 pENTDAA_payload->PID.PartID = I3C_GET_PART_ID(PID);
7154 pENTDAA_payload->PID.MIPIID = I3C_GET_MIPIID(PID);
7155 }
7156 }
7157
7158 return status;
7159 }
7160
7161 /**
7162 * @}
7163 */
7164
7165 /**
7166 * @}
7167 */
7168
7169 /* Private functions -------------------------------------------------------------------------------------------------*/
7170 /** @defgroup I3C_Private_Functions I3C Private Functions
7171 * @{
7172 */
7173
7174 /**
7175 * @brief Interrupt Sub-Routine which handles target received events.
7176 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7177 * for the specified I3C.
7178 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7179 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7180 */
I3C_Tgt_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7181 static HAL_StatusTypeDef I3C_Tgt_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7182 {
7183 uint32_t tmpevent = 0U;
7184
7185 /* I3C Rx FIFO not empty interrupt Check */
7186 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7187 {
7188 /* Call receive treatment function */
7189 hi3c->ptrRxFunc(hi3c);
7190 }
7191
7192 /* I3C target complete controller-role hand-off procedure (direct GETACCR CCC) event management --------------------*/
7193 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRUPDF) != RESET)
7194 {
7195 /* Clear controller-role update flag */
7196 LL_I3C_ClearFlag_CRUPD(hi3c->Instance);
7197
7198 /* Set Identifier EVENT_ID_GETACCCR */
7199 tmpevent |= EVENT_ID_GETACCCR;
7200 }
7201
7202 /* I3C target receive any direct GETxxx CCC event management -------------------------------------------------------*/
7203 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_GETF) != RESET)
7204 {
7205 /* Clear GETxxx CCC flag */
7206 LL_I3C_ClearFlag_GET(hi3c->Instance);
7207
7208 /* Set Identifier EVENT_ID_GETx */
7209 tmpevent |= EVENT_ID_GETx;
7210 }
7211
7212 /* I3C target receive get status command (direct GETSTATUS CCC) event management -----------------------------------*/
7213 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_STAF) != RESET)
7214 {
7215 /* Clear GETSTATUS CCC flag */
7216 LL_I3C_ClearFlag_STA(hi3c->Instance);
7217
7218 /* Set Identifier EVENT_ID_GETSTATUS */
7219 tmpevent |= EVENT_ID_GETSTATUS;
7220 }
7221
7222 /* I3C target receive a dynamic address update (ENTDAA/RSTDAA/SETNEWDA CCC) event management -----------------------*/
7223 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_DAUPDF) != RESET)
7224 {
7225 /* Clear dynamic address update flag */
7226 LL_I3C_ClearFlag_DAUPD(hi3c->Instance);
7227
7228 /* Set Identifier EVENT_ID_DAU */
7229 tmpevent |= EVENT_ID_DAU;
7230 }
7231
7232 /* I3C target receive maximum write length update (direct SETMWL CCC) event management -----------------------------*/
7233 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_MWLUPDF) != RESET)
7234 {
7235 /* Clear SETMWL CCC flag */
7236 LL_I3C_ClearFlag_MWLUPD(hi3c->Instance);
7237
7238 /* Set Identifier EVENT_ID_SETMWL */
7239 tmpevent |= EVENT_ID_SETMWL;
7240 }
7241
7242 /* I3C target receive maximum read length update(direct SETMRL CCC) event management -------------------------------*/
7243 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_MRLUPDF) != RESET)
7244 {
7245 /* Clear SETMRL CCC flag */
7246 LL_I3C_ClearFlag_MRLUPD(hi3c->Instance);
7247
7248 /* Set Identifier EVENT_ID_SETMRL */
7249 tmpevent |= EVENT_ID_SETMRL;
7250 }
7251
7252 /* I3C target detect reset pattern (broadcast or direct RSTACT CCC) event management -------------------------------*/
7253 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_RSTF) != RESET)
7254 {
7255 /* Clear reset pattern flag */
7256 LL_I3C_ClearFlag_RST(hi3c->Instance);
7257
7258 /* Set Identifier EVENT_ID_RSTACT */
7259 tmpevent |= EVENT_ID_RSTACT;
7260 }
7261
7262 /* I3C target receive activity state update (direct or broadcast ENTASx) CCC event management ----------------------*/
7263 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_ASUPDF) != RESET)
7264 {
7265 /* Clear ENTASx CCC flag */
7266 LL_I3C_ClearFlag_ASUPD(hi3c->Instance);
7267
7268 /* Set Identifier EVENT_ID_ENTASx */
7269 tmpevent |= EVENT_ID_ENTASx;
7270 }
7271
7272 /* I3C target receive a direct or broadcast ENEC/DISEC CCC event management ----------------------------------------*/
7273 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_INTUPDF) != RESET)
7274 {
7275 /* Clear ENEC/DISEC CCC flag */
7276 LL_I3C_ClearFlag_INTUPD(hi3c->Instance);
7277
7278 /* Set Identifier EVENT_ID_ENEC_DISEC */
7279 tmpevent |= EVENT_ID_ENEC_DISEC;
7280 }
7281
7282 /* I3C target receive a broadcast DEFTGTS CCC event management -----------------------------------------------------*/
7283 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_DEFF) != RESET)
7284 {
7285 /* Clear DEFTGTS CCC flag */
7286 LL_I3C_ClearFlag_DEF(hi3c->Instance);
7287
7288 /* Set Identifier EVENT_ID_DEFTGTS */
7289 tmpevent |= EVENT_ID_DEFTGTS;
7290 }
7291
7292 /* I3C target receive a group addressing (broadcast DEFGRPA CCC) event management ----------------------------------*/
7293 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_GRPF) != RESET)
7294 {
7295 /* Clear DEFGRPA CCC flag */
7296 LL_I3C_ClearFlag_GRP(hi3c->Instance);
7297
7298 /* Set Identifier EVENT_ID_DEFGRPA */
7299 tmpevent |= EVENT_ID_DEFGRPA;
7300 }
7301
7302 /* I3C target wakeup event management ----------------------------------*/
7303 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7304 {
7305 /* Clear WKP flag */
7306 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7307
7308 /* Set Identifier EVENT_ID_WKP */
7309 tmpevent |= EVENT_ID_WKP;
7310 }
7311
7312 if (tmpevent != 0U)
7313 {
7314 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7315 /* Call registered callback */
7316 hi3c->NotifyCallback(hi3c, tmpevent);
7317 #else
7318 /* Asynchronous receive CCC event Callback */
7319 HAL_I3C_NotifyCallback(hi3c, tmpevent);
7320 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7321 }
7322
7323 /* Update handle state parameter */
7324 I3C_StateUpdate(hi3c);
7325
7326 return HAL_OK;
7327 }
7328
7329 /**
7330 * @brief Interrupt Sub-Routine which handles Controller received events.
7331 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7332 * for the specified I3C.
7333 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7334 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7335 */
I3C_Ctrl_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7336 static HAL_StatusTypeDef I3C_Ctrl_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7337 {
7338 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
7339 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
7340 {
7341 /* Clear IBI request flag */
7342 LL_I3C_ClearFlag_IBI(hi3c->Instance);
7343
7344 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7345 /* Call registered callback */
7346 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
7347 #else
7348 /* Asynchronous IBI event Callback */
7349 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
7350 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7351 }
7352
7353 /* I3C controller controller-role request event management ---------------------------------------------------------*/
7354 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
7355 {
7356 /* Clear controller-role request flag */
7357 LL_I3C_ClearFlag_CR(hi3c->Instance);
7358
7359 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7360 /* Call registered callback */
7361 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
7362 #else
7363 /* Asynchronous controller-role event Callback */
7364 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
7365 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7366 }
7367
7368 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
7369 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
7370 {
7371 /* Clear hot-join flag */
7372 LL_I3C_ClearFlag_HJ(hi3c->Instance);
7373
7374 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7375 /* Call registered callback */
7376 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
7377 #else
7378 /* Asynchronous hot-join event Callback */
7379 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
7380 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7381 }
7382
7383 /* Update handle state parameter */
7384 I3C_StateUpdate(hi3c);
7385
7386 return HAL_OK;
7387 }
7388
7389 /**
7390 * @brief Interrupt Sub-Routine which handles target hot join event.
7391 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7392 * for the specified I3C.
7393 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7394 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7395 */
I3C_Tgt_HotJoin_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7396 static HAL_StatusTypeDef I3C_Tgt_HotJoin_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7397 {
7398 /* I3C target receive a dynamic address update event management */
7399 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_DAUPDF) != RESET)
7400 {
7401 /* Clear dynamic address update flag */
7402 LL_I3C_ClearFlag_DAUPD(hi3c->Instance);
7403
7404 /* Disable dynamic address update and error interrupts */
7405 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_HOTJOIN);
7406
7407 /* Check the validity of the own dynamic address */
7408 if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) == 1U)
7409 {
7410 /* Update handle state parameter */
7411 I3C_StateUpdate(hi3c);
7412
7413 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7414
7415 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7416 /* Call registered callback */
7417 hi3c->TgtHotJoinCallback(hi3c, (uint8_t)LL_I3C_GetOwnDynamicAddress(hi3c->Instance));
7418 #else
7419 /* Asynchronous receive ENTDAA/RSTDAA/SETNEWDA CCC event Callback */
7420 HAL_I3C_TgtHotJoinCallback(hi3c, (uint8_t)LL_I3C_GetOwnDynamicAddress(hi3c->Instance));
7421 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7422 }
7423 else
7424 {
7425 hi3c->ErrorCode = HAL_I3C_ERROR_DYNAMIC_ADDR;
7426
7427 /* Call error treatment function */
7428 I3C_ErrorTreatment(hi3c);
7429 }
7430 }
7431 return HAL_OK;
7432 }
7433
7434 /**
7435 * @brief Interrupt Sub-Routine which handles target control role event.
7436 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7437 * for the specified I3C.
7438 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7439 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7440 */
I3C_Tgt_CtrlRole_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7441 static HAL_StatusTypeDef I3C_Tgt_CtrlRole_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7442 {
7443 /* I3C target complete controller-role hand-off procedure (direct GETACCR CCC) event management -------------------*/
7444 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRUPDF) != RESET)
7445 {
7446 /* Clear controller-role update flag */
7447 LL_I3C_ClearFlag_CRUPD(hi3c->Instance);
7448
7449 /* Disable controller-role update and error interrupts */
7450 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_CTRLROLE);
7451
7452 /* Update handle state parameter */
7453 I3C_StateUpdate(hi3c);
7454
7455 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7456
7457 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7458 /* Call registered callback */
7459 hi3c->NotifyCallback(hi3c, EVENT_ID_GETACCCR);
7460 #else
7461 /* Asynchronous receive GETACCR CCC event Callback */
7462 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_GETACCCR);
7463 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7464 }
7465 return HAL_OK;
7466 }
7467
7468 /**
7469 * @brief Interrupt Sub-Routine which handles target IBI event.
7470 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7471 * for the specified I3C.
7472 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7473 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7474 */
I3C_Tgt_IBI_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7475 static HAL_StatusTypeDef I3C_Tgt_IBI_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7476 {
7477 /* I3C target IBI end process event management ---------------------------------------------------------------------*/
7478 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIENDF) != RESET)
7479 {
7480 /* Clear IBI end flag */
7481 LL_I3C_ClearFlag_IBIEND(hi3c->Instance);
7482
7483 /* Disable IBI end and error interrupts */
7484 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_IBI);
7485
7486 /* Update handle state parameter */
7487 I3C_StateUpdate(hi3c);
7488
7489 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7490
7491 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7492 /* Call registered callback */
7493 hi3c->NotifyCallback(hi3c, EVENT_ID_IBIEND);
7494 #else
7495 /* Asynchronous IBI end event Callback */
7496 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBIEND);
7497 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7498 }
7499 return HAL_OK;
7500 }
7501
7502 /**
7503 * @brief Interrupt Sub-Routine which handles target transmit data in Interrupt mode.
7504 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7505 * for the specified I3C.
7506 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7507 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7508 */
I3C_Tgt_Tx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7509 static HAL_StatusTypeDef I3C_Tgt_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7510 {
7511 /* Check that a Tx process is ongoing */
7512 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
7513 {
7514 /* I3C Tx FIFO not full interrupt Check */
7515 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7516 {
7517 if (hi3c->TxXferCount > 0U)
7518 {
7519 /* Call transmit treatment function */
7520 hi3c->ptrTxFunc(hi3c);
7521 }
7522 }
7523
7524 /* I3C target frame complete event Check */
7525 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7526 {
7527 /* Clear frame complete flag */
7528 LL_I3C_ClearFlag_FC(hi3c->Instance);
7529
7530 /* Check if all data bytes are transmitted */
7531 if (LL_I3C_GetXferDataCount(hi3c->Instance) == hi3c->pXferData->TxBuf.Size)
7532 {
7533 /* Disable Tx process interrupts */
7534 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_TX_IT);
7535
7536 /* Update handle state parameter */
7537 I3C_StateUpdate(hi3c);
7538
7539 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7540
7541 /* Call the transmit complete callback to inform upper layer of End of Transfer */
7542 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7543 hi3c->TgtTxCpltCallback(hi3c);
7544 #else
7545 HAL_I3C_TgtTxCpltCallback(hi3c);
7546 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7547 }
7548 else
7549 {
7550 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7551
7552 /* Call error treatment function */
7553 I3C_ErrorTreatment(hi3c);
7554 }
7555 }
7556
7557 /* I3C target wakeup event management ----------------------------------*/
7558 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7559 {
7560 /* Clear WKP flag */
7561 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7562
7563 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7564 /* Call registered callback */
7565 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7566 #else
7567 /* Asynchronous receive CCC event Callback */
7568 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7569 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7570 }
7571 }
7572
7573 return HAL_OK;
7574 }
7575
7576 /**
7577 * @brief Interrupt Sub-Routine which handles target receive data in Interrupt mode.
7578 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7579 * for the specified I3C.
7580 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7581 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7582 */
I3C_Tgt_Rx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7583 static HAL_StatusTypeDef I3C_Tgt_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7584 {
7585 /* Check that an Rx process is ongoing */
7586 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
7587 {
7588 /* I3C Rx FIFO not empty interrupt Check */
7589 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7590 {
7591 if (hi3c->RxXferCount > 0U)
7592 {
7593 /* Call receive treatment function */
7594 hi3c->ptrRxFunc(hi3c);
7595 }
7596 }
7597
7598 /* I3C target frame complete event Check */
7599 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7600 {
7601 /* Clear frame complete flag */
7602 LL_I3C_ClearFlag_FC(hi3c->Instance);
7603
7604 /* Check if all data bytes are received */
7605 if (LL_I3C_GetXferDataCount(hi3c->Instance) == hi3c->pXferData->RxBuf.Size)
7606 {
7607 /* Disable Rx process interrupts */
7608 I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT);
7609
7610 /* Update handle state parameter */
7611 I3C_StateUpdate(hi3c);
7612
7613 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7614
7615 /* Call the receive complete callback to inform upper layer of End of Transfer */
7616 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7617 hi3c->TgtRxCpltCallback(hi3c);
7618 #else
7619 HAL_I3C_TgtRxCpltCallback(hi3c);
7620 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7621 }
7622 else
7623 {
7624 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7625
7626 /* Call error treatment function */
7627 I3C_ErrorTreatment(hi3c);
7628 }
7629 }
7630
7631 /* I3C target wakeup event management ----------------------------------*/
7632 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7633 {
7634 /* Clear WKP flag */
7635 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7636
7637 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7638 /* Call registered callback */
7639 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7640 #else
7641 /* Asynchronous receive CCC event Callback */
7642 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7643 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7644 }
7645 }
7646
7647 return HAL_OK;
7648 }
7649
7650 #if defined(HAL_DMA_MODULE_ENABLED)
7651 /**
7652 * @brief Interrupt Sub-Routine which handles target transmit data in DMA mode.
7653 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7654 * for the specified I3C.
7655 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7656 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7657 */
I3C_Tgt_Tx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7658 static HAL_StatusTypeDef I3C_Tgt_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7659 {
7660 /* Check that a Tx process is ongoing */
7661 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
7662 {
7663 /* I3C target frame complete event Check */
7664 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7665 {
7666 /* Clear frame complete flag */
7667 LL_I3C_ClearFlag_FC(hi3c->Instance);
7668
7669 /* Check if all data bytes are transmitted */
7670 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U)
7671 {
7672 /* Disable Tx process interrupts */
7673 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
7674
7675 /* Update handle state parameter */
7676 I3C_StateUpdate(hi3c);
7677
7678 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7679
7680 /* Update the number of remaining data bytes */
7681 hi3c->TxXferCount = 0U;
7682
7683 /* Call target transmit complete callback to inform upper layer of End of Transfer */
7684 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7685 hi3c->TgtTxCpltCallback(hi3c);
7686 #else
7687 HAL_I3C_TgtTxCpltCallback(hi3c);
7688 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7689 }
7690 else
7691 {
7692 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7693
7694 /* Call error treatment function */
7695 I3C_ErrorTreatment(hi3c);
7696 }
7697 }
7698
7699 /* I3C target wakeup event management ----------------------------------*/
7700 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7701 {
7702 /* Clear WKP flag */
7703 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7704
7705 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7706 /* Call registered callback */
7707 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7708 #else
7709 /* Asynchronous receive CCC event Callback */
7710 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7711 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7712 }
7713 }
7714
7715 return HAL_OK;
7716 }
7717
7718 /**
7719 * @brief Interrupt Sub-Routine which handles target receive data in DMA mode.
7720 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7721 * for the specified I3C.
7722 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7723 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7724 */
I3C_Tgt_Rx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7725 static HAL_StatusTypeDef I3C_Tgt_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7726 {
7727 /* Check that a Rx process is ongoing */
7728 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
7729 {
7730 /* I3C target frame complete event Check */
7731 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7732 {
7733 /* Clear frame complete flag */
7734 LL_I3C_ClearFlag_FC(hi3c->Instance);
7735
7736 /* Check if all data bytes are received */
7737 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U)
7738 {
7739 /* Disable Rx process interrupts */
7740 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
7741
7742 /* Update handle state parameter */
7743 I3C_StateUpdate(hi3c);
7744
7745 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7746
7747 /* Update the number of remaining data bytes */
7748 hi3c->RxXferCount = 0U;
7749
7750 /* Call target receive complete callback to inform upper layer of End of Transfer */
7751 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7752 hi3c->TgtRxCpltCallback(hi3c);
7753 #else
7754 HAL_I3C_TgtRxCpltCallback(hi3c);
7755 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7756 }
7757 else
7758 {
7759 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
7760
7761 /* Call error treatment function */
7762 I3C_ErrorTreatment(hi3c);
7763 }
7764 }
7765
7766 /* I3C target wakeup event management ----------------------------------*/
7767 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_WKPF) != RESET)
7768 {
7769 /* Clear WKP flag */
7770 LL_I3C_ClearFlag_WKP(hi3c->Instance);
7771
7772 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7773 /* Call registered callback */
7774 hi3c->NotifyCallback(hi3c, EVENT_ID_WKP);
7775 #else
7776 /* Asynchronous receive CCC event Callback */
7777 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP);
7778 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7779 }
7780 }
7781
7782 return HAL_OK;
7783 }
7784 #endif /* HAL_DMA_MODULE_ENABLED */
7785
7786 /**
7787 * @brief Interrupt Sub-Routine which handles controller transmission in interrupt mode.
7788 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7789 * for the specified I3C.
7790 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7791 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7792 */
I3C_Ctrl_Tx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7793 static HAL_StatusTypeDef I3C_Ctrl_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7794 {
7795 /* Check that a Tx process is ongoing */
7796 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
7797 {
7798 /* Check if Control FIFO requests data */
7799 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
7800 {
7801 if (hi3c->ControlXferCount > 0U)
7802 {
7803 /* Call control data treatment function */
7804 I3C_ControlDataTreatment(hi3c);
7805 }
7806 }
7807
7808 /* I3C Tx FIFO not full interrupt Check */
7809 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7810 {
7811 if (hi3c->TxXferCount > 0U)
7812 {
7813 /* Call Transmit treatment function */
7814 hi3c->ptrTxFunc(hi3c);
7815 }
7816 }
7817
7818 /* I3C target frame complete event Check */
7819 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7820 {
7821 /* Clear frame complete flag */
7822 LL_I3C_ClearFlag_FC(hi3c->Instance);
7823
7824 if (hi3c->ControlXferCount == 0U)
7825 {
7826 /* Disable Tx process interrupts */
7827 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT);
7828
7829 /* Update handle state parameter */
7830 I3C_StateUpdate(hi3c);
7831
7832 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7833
7834 /* Call the transmit complete callback to inform upper layer of End of Transfer */
7835 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7836 hi3c->CtrlTxCpltCallback(hi3c);
7837 #else
7838 HAL_I3C_CtrlTxCpltCallback(hi3c);
7839 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7840 }
7841 else
7842 {
7843 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7844
7845 /* Call the transmit complete callback */
7846 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7847 hi3c->CtrlTxCpltCallback(hi3c);
7848 #else
7849 HAL_I3C_CtrlTxCpltCallback(hi3c);
7850 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7851
7852 /* Then Initiate a Start condition */
7853 LL_I3C_RequestTransfer(hi3c->Instance);
7854
7855 }
7856 }
7857 }
7858 return HAL_OK;
7859 }
7860
7861 /**
7862 * @brief Interrupt Sub-Routine which handles controller reception in interrupt mode.
7863 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7864 * for the specified I3C.
7865 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7866 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7867 */
I3C_Ctrl_Rx_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7868 static HAL_StatusTypeDef I3C_Ctrl_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7869 {
7870 /* Check that an Rx process is ongoing */
7871 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
7872 {
7873 /* Check if Control FIFO requests data */
7874 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
7875 {
7876 if (hi3c->ControlXferCount > 0U)
7877 {
7878 /* Call control data treatment function */
7879 I3C_ControlDataTreatment(hi3c);
7880 }
7881 }
7882
7883 /* I3C Rx FIFO not empty interrupt Check */
7884 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7885 {
7886 if (hi3c->RxXferCount > 0U)
7887 {
7888 /* Call receive treatment function */
7889 hi3c->ptrRxFunc(hi3c);
7890 }
7891 }
7892
7893 /* I3C Tx FIFO not full interrupt Check */
7894 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7895 {
7896 if (hi3c->TxXferCount > 0U)
7897 {
7898 /* Call Transmit treatment function */
7899 hi3c->ptrTxFunc(hi3c);
7900 }
7901 }
7902
7903 /* I3C target frame complete event Check */
7904 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7905 {
7906 /* Clear frame complete flag */
7907 LL_I3C_ClearFlag_FC(hi3c->Instance);
7908
7909 if (hi3c->ControlXferCount == 0U)
7910 {
7911 /* Disable Rx process interrupts */
7912 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
7913
7914 /* Update handle state parameter */
7915 I3C_StateUpdate(hi3c);
7916
7917 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7918
7919 /* Call the receive complete callback */
7920 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7921 hi3c->CtrlRxCpltCallback(hi3c);
7922 #else
7923 HAL_I3C_CtrlRxCpltCallback(hi3c);
7924 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7925 }
7926 else
7927 {
7928 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
7929
7930 /* Call the receive complete callback */
7931 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
7932 hi3c->CtrlRxCpltCallback(hi3c);
7933 #else
7934 HAL_I3C_CtrlRxCpltCallback(hi3c);
7935 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
7936
7937 /* Then Initiate a Start condition */
7938 LL_I3C_RequestTransfer(hi3c->Instance);
7939 }
7940 }
7941 }
7942 return HAL_OK;
7943 }
7944
7945 /**
7946 * @brief Interrupt Sub-Routine which handles controller multiple transmission/reception in interrupt mode.
7947 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
7948 * for the specified I3C.
7949 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
7950 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
7951 */
I3C_Ctrl_Multiple_Xfer_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)7952 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
7953 {
7954 /* Check that a Tx/Rx process is ongoing */
7955 if (hi3c->State == HAL_I3C_STATE_BUSY_TX_RX)
7956 {
7957 /* Check if Control FIFO requests data */
7958 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
7959 {
7960 if (hi3c->ControlXferCount > 0U)
7961 {
7962 /* Call control data treatment function */
7963 I3C_ControlDataTreatment(hi3c);
7964 }
7965 }
7966
7967 /* I3C Tx FIFO not full interrupt Check */
7968 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
7969 {
7970 if (hi3c->TxXferCount > 0U)
7971 {
7972 /* Call Transmit treatment function */
7973 hi3c->ptrTxFunc(hi3c);
7974 }
7975 }
7976
7977 /* I3C Rx FIFO not empty interrupt Check */
7978 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
7979 {
7980 if (hi3c->RxXferCount > 0U)
7981 {
7982 /* Call receive treatment function */
7983 hi3c->ptrRxFunc(hi3c);
7984 }
7985 }
7986
7987 /* I3C target frame complete event Check */
7988 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
7989 {
7990 /* Clear frame complete flag */
7991 LL_I3C_ClearFlag_FC(hi3c->Instance);
7992
7993 if (hi3c->ControlXferCount == 0U)
7994 {
7995 /* Disable Tx process interrupts */
7996 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT);
7997
7998 /* Disable Rx process interrupts */
7999 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
8000
8001 /* Update handle state parameter */
8002 I3C_StateUpdate(hi3c);
8003
8004 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8005
8006 /* Call the transmit, receive complete callback to inform upper layer of End of Transfer */
8007 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8008 hi3c->CtrlMultipleXferCpltCallback(hi3c);
8009 #else
8010 HAL_I3C_CtrlMultipleXferCpltCallback(hi3c);
8011 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8012 }
8013 else
8014 {
8015 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8016
8017 /* Then Initiate a Start condition */
8018 LL_I3C_RequestTransfer(hi3c->Instance);
8019 }
8020 }
8021 }
8022 return HAL_OK;
8023 }
8024
8025 /**
8026 * @brief Interrupt Sub-Routine which handles controller transmission and Controller received events
8027 * in interrupt mode.
8028 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8029 * for the specified I3C.
8030 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8031 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8032 */
I3C_Ctrl_Tx_Listen_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8033 static HAL_StatusTypeDef I3C_Ctrl_Tx_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8034 {
8035 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
8036 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
8037 {
8038 /* Clear IBI request flag */
8039 LL_I3C_ClearFlag_IBI(hi3c->Instance);
8040
8041 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8042 /* Call registered callback */
8043 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
8044 #else
8045 /* Asynchronous IBI event Callback */
8046 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
8047 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8048 }
8049
8050 /* I3C controller controller-role request event management ---------------------------------------------------------*/
8051 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
8052 {
8053 /* Clear controller-role request flag */
8054 LL_I3C_ClearFlag_CR(hi3c->Instance);
8055
8056 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8057 /* Call registered callback */
8058 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
8059 #else
8060 /* Asynchronous controller-role event Callback */
8061 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
8062 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8063 }
8064
8065 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
8066 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
8067 {
8068 /* Clear hot-join flag */
8069 LL_I3C_ClearFlag_HJ(hi3c->Instance);
8070
8071 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8072 /* Call registered callback */
8073 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
8074 #else
8075 /* Asynchronous hot-join event Callback */
8076 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
8077 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8078 }
8079
8080 /* ISR controller transmission */
8081 return (I3C_Ctrl_Tx_ISR(hi3c, itMasks));
8082 }
8083
8084 /**
8085 * @brief Interrupt Sub-Routine which handles controller reception and Controller received events in interrupt mode.
8086 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8087 * for the specified I3C.
8088 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8089 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8090 */
I3C_Ctrl_Rx_Listen_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8091 static HAL_StatusTypeDef I3C_Ctrl_Rx_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8092 {
8093 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
8094 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
8095 {
8096 /* Clear IBI request flag */
8097 LL_I3C_ClearFlag_IBI(hi3c->Instance);
8098
8099 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8100 /* Call registered callback */
8101 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
8102 #else
8103 /* Asynchronous IBI event Callback */
8104 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
8105 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8106 }
8107
8108 /* I3C controller controller-role request event management ---------------------------------------------------------*/
8109 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
8110 {
8111 /* Clear controller-role request flag */
8112 LL_I3C_ClearFlag_CR(hi3c->Instance);
8113
8114 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8115 /* Call registered callback */
8116 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
8117 #else
8118 /* Asynchronous controller-role event Callback */
8119 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
8120 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8121 }
8122
8123 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
8124 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
8125 {
8126 /* Clear hot-join flag */
8127 LL_I3C_ClearFlag_HJ(hi3c->Instance);
8128
8129 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8130 /* Call registered callback */
8131 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
8132 #else
8133 /* Asynchronous hot-join event Callback */
8134 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
8135 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8136 }
8137
8138 /* ISR controller reception */
8139 return (I3C_Ctrl_Rx_ISR(hi3c, itMasks));
8140 }
8141
8142 /**
8143 * @brief Interrupt Sub-Routine which handles controller multiple transmission/reception and
8144 * Controller received eventsin interrupt mode.
8145 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8146 * for the specified I3C.
8147 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8148 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8149 */
I3C_Ctrl_Multiple_Xfer_Listen_Event_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8150 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_Listen_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8151 {
8152 /* I3C controller receive IBI event management ---------------------------------------------------------------------*/
8153 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_IBIF) != RESET)
8154 {
8155 /* Clear IBI request flag */
8156 LL_I3C_ClearFlag_IBI(hi3c->Instance);
8157
8158 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8159 /* Call registered callback */
8160 hi3c->NotifyCallback(hi3c, EVENT_ID_IBI);
8161 #else
8162 /* Asynchronous IBI event Callback */
8163 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI);
8164 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8165 }
8166
8167 /* I3C controller controller-role request event management ---------------------------------------------------------*/
8168 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CRF) != RESET)
8169 {
8170 /* Clear controller-role request flag */
8171 LL_I3C_ClearFlag_CR(hi3c->Instance);
8172
8173 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8174 /* Call registered callback */
8175 hi3c->NotifyCallback(hi3c, EVENT_ID_CR);
8176 #else
8177 /* Asynchronous controller-role event Callback */
8178 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR);
8179 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8180 }
8181
8182 /* I3C controller hot-join event management ------------------------------------------------------------------------*/
8183 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_HJF) != RESET)
8184 {
8185 /* Clear hot-join flag */
8186 LL_I3C_ClearFlag_HJ(hi3c->Instance);
8187
8188 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8189 /* Call registered callback */
8190 hi3c->NotifyCallback(hi3c, EVENT_ID_HJ);
8191 #else
8192 /* Asynchronous hot-join event Callback */
8193 HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ);
8194 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8195 }
8196
8197 /* ISR controller transmission/reception */
8198 return (I3C_Ctrl_Multiple_Xfer_ISR(hi3c, itMasks));
8199 }
8200 /**
8201 * @brief Interrupt Sub-Routine which handles controller CCC Dynamic Address Assignment command in interrupt mode.
8202 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8203 * for the specified I3C.
8204 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8205 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8206 */
I3C_Ctrl_DAA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8207 static HAL_StatusTypeDef I3C_Ctrl_DAA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8208 {
8209 uint64_t target_payload = 0U;
8210
8211 /* Check that a Dynamic Address Assignment process is ongoing */
8212 if (hi3c->State == HAL_I3C_STATE_BUSY_DAA)
8213 {
8214 /* I3C Control FIFO not full interrupt Check */
8215 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_CFNFF) != RESET)
8216 {
8217 /* Write ENTDAA CCC information in the control register */
8218 LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_ENTDAA, 0U, LL_I3C_GENERATE_STOP);
8219 }
8220
8221 /* I3C Tx FIFO not full interrupt Check */
8222 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_TXFNFF) != RESET)
8223 {
8224 /* Check on the Rx FIFO threshold to know the Dynamic Address Assignment treatment process : byte or word */
8225 if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4)
8226 {
8227 /* For loop to get target payload */
8228 for (uint32_t index = 0U; index < 8U; index++)
8229 {
8230 /* Retrieve payload byte by byte */
8231 target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData8(hi3c->Instance) << (index * 8U));
8232 }
8233 }
8234 else
8235 {
8236 /* Retrieve first 32 bits payload */
8237 target_payload = (uint64_t)LL_I3C_ReceiveData32(hi3c->Instance);
8238
8239 /* Retrieve second 32 bits payload */
8240 target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData32(hi3c->Instance) << 32U);
8241 }
8242
8243 /* Call the corresponding callback */
8244 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8245 hi3c->TgtReqDynamicAddrCallback(hi3c, target_payload);
8246 #else
8247 HAL_I3C_TgtReqDynamicAddrCallback(hi3c, target_payload);
8248 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
8249 }
8250
8251 /* I3C frame complete event Check */
8252 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8253 {
8254 /* Clear frame complete flag */
8255 LL_I3C_ClearFlag_FC(hi3c->Instance);
8256
8257 /* Disable Dynamic Address Assignment process interrupts */
8258 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_DAA_IT);
8259
8260 /* Update handle state parameter */
8261 I3C_StateUpdate(hi3c);
8262
8263 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8264
8265 /* Call the Dynamic Address Assignment complete callback */
8266 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8267 hi3c->CtrlDAACpltCallback(hi3c);
8268 #else
8269 HAL_I3C_CtrlDAACpltCallback(hi3c);
8270 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8271 }
8272 }
8273 return HAL_OK;
8274 }
8275
8276 #if defined(HAL_DMA_MODULE_ENABLED)
8277 /**
8278 * @brief Interrupt Sub-Routine which handles controller transmit data in DMA mode.
8279 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8280 * for the specified I3C.
8281 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8282 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8283 */
I3C_Ctrl_Tx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8284 static HAL_StatusTypeDef I3C_Ctrl_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8285 {
8286 /* Check that a Tx process is ongoing */
8287 if (hi3c->State == HAL_I3C_STATE_BUSY_TX)
8288 {
8289 /* I3C target frame complete event Check */
8290 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8291 {
8292 /* Clear frame complete flag */
8293 LL_I3C_ClearFlag_FC(hi3c->Instance);
8294
8295 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U)
8296 {
8297 /* Check if all data bytes are transmitted */
8298 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U)
8299 {
8300 /* Disable Tx process interrupts */
8301 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
8302
8303 /* Update handle state parameter */
8304 I3C_StateUpdate(hi3c);
8305
8306 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8307
8308 /* Update the number of remaining data bytes */
8309 hi3c->TxXferCount = 0U;
8310
8311 /* Call controller transmit complete callback to inform upper layer of End of Transfer */
8312 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8313 hi3c->CtrlTxCpltCallback(hi3c);
8314 #else
8315 HAL_I3C_CtrlTxCpltCallback(hi3c);
8316 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8317 }
8318 else
8319 {
8320 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8321
8322 /* Call error treatment function */
8323 I3C_ErrorTreatment(hi3c);
8324 }
8325 }
8326 else
8327 {
8328 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8329
8330 /* Call the transmit complete callback */
8331 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8332 hi3c->CtrlTxCpltCallback(hi3c);
8333 #else
8334 HAL_I3C_CtrlTxCpltCallback(hi3c);
8335 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8336
8337 /* Then Initiate a Start condition */
8338 LL_I3C_RequestTransfer(hi3c->Instance);
8339 }
8340 }
8341 }
8342 return HAL_OK;
8343 }
8344
8345 /**
8346 * @brief Interrupt Sub-Routine which handles controller receive data in DMA mode.
8347 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8348 * for the specified I3C.
8349 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8350 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8351 */
I3C_Ctrl_Rx_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8352 static HAL_StatusTypeDef I3C_Ctrl_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8353 {
8354 /* Check that an Rx process is ongoing */
8355 if (hi3c->State == HAL_I3C_STATE_BUSY_RX)
8356 {
8357 /* I3C target frame complete event Check */
8358 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8359 {
8360 /* Clear frame complete flag */
8361 LL_I3C_ClearFlag_FC(hi3c->Instance);
8362
8363 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U)
8364 {
8365 /* Check if all data bytes are received */
8366 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U)
8367 {
8368 /* Disable Rx process interrupts */
8369 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
8370
8371 /* Update handle state parameter */
8372 I3C_StateUpdate(hi3c);
8373
8374 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8375
8376 /* Update the number of remaining data bytes */
8377 hi3c->RxXferCount = 0U;
8378
8379 /* Call controller receive complete callback */
8380 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8381 hi3c->CtrlRxCpltCallback(hi3c);
8382 #else
8383 HAL_I3C_CtrlRxCpltCallback(hi3c);
8384 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8385 }
8386 else
8387 {
8388 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8389
8390 /* Call error treatment function */
8391 I3C_ErrorTreatment(hi3c);
8392 }
8393 }
8394 else
8395 {
8396 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8397
8398 /* Call the receive complete callback */
8399 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8400 hi3c->CtrlRxCpltCallback(hi3c);
8401 #else
8402 HAL_I3C_CtrlRxCpltCallback(hi3c);
8403 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8404
8405 /* Then Initiate a Start condition */
8406 LL_I3C_RequestTransfer(hi3c->Instance);
8407 }
8408 }
8409 }
8410 return HAL_OK;
8411 }
8412
8413 /**
8414 * @brief Interrupt Sub-Routine which handles controller multiple receive and transmit data in DMA mode.
8415 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8416 * for the specified I3C.
8417 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8418 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8419 */
I3C_Ctrl_Multiple_Xfer_DMA_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8420 static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8421 {
8422 /* Check that an Rx or Tx process is ongoing */
8423 if (hi3c->State == HAL_I3C_STATE_BUSY_TX_RX)
8424 {
8425 /* I3C target frame complete event Check */
8426 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8427 {
8428 /* Clear frame complete flag */
8429 LL_I3C_ClearFlag_FC(hi3c->Instance);
8430
8431 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U)
8432 {
8433 /* Check if all data bytes are received or transmitted */
8434 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U)
8435 {
8436 if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U)
8437 {
8438 /* Disable transfer Tx/Rx process interrupts */
8439 I3C_Disable_IRQ(hi3c, I3C_XFER_DMA);
8440
8441 /* Update handle state parameter */
8442 I3C_StateUpdate(hi3c);
8443
8444 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8445
8446 /* Update the number of remaining data bytes */
8447 hi3c->RxXferCount = 0U;
8448
8449 /* Update the number of remaining data bytes */
8450 hi3c->TxXferCount = 0U;
8451
8452 /* Call controller transmit, receive complete callback to inform upper layer of End of Transfer */
8453 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U)
8454 hi3c->CtrlMultipleXferCpltCallback(hi3c);
8455 #else
8456 HAL_I3C_CtrlMultipleXferCpltCallback(hi3c);
8457 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */
8458 }
8459 else
8460 {
8461 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8462
8463 /* Call error treatment function */
8464 I3C_ErrorTreatment(hi3c);
8465 }
8466 }
8467 else
8468 {
8469 hi3c->ErrorCode = HAL_I3C_ERROR_SIZE;
8470
8471 /* Call error treatment function */
8472 I3C_ErrorTreatment(hi3c);
8473 }
8474 }
8475 else
8476 {
8477 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
8478
8479 /* Then Initiate a Start condition */
8480 LL_I3C_RequestTransfer(hi3c->Instance);
8481 }
8482 }
8483 }
8484 return HAL_OK;
8485 }
8486 #endif /* HAL_DMA_MODULE_ENABLED */
8487
8488 /**
8489 * @brief Interrupt Sub-Routine which handles abort process in interrupt mode.
8490 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
8491 * for the specified I3C.
8492 * @param itMasks : [IN] Flag Interrupt Masks flags to handle.
8493 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8494 */
I3C_Abort_ISR(struct __I3C_HandleTypeDef * hi3c,uint32_t itMasks)8495 static HAL_StatusTypeDef I3C_Abort_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itMasks)
8496 {
8497 /* Check that an Abort process is ongoing */
8498 if (hi3c->State == HAL_I3C_STATE_ABORT)
8499 {
8500 /* I3C Rx FIFO not empty interrupt Check */
8501 if (I3C_CHECK_FLAG(itMasks, HAL_I3C_FLAG_RXFNEF) != RESET)
8502 {
8503 if (LL_I3C_IsActiveFlag_DOVR(hi3c->Instance) == 1U)
8504 {
8505 /* Flush remaining Rx data */
8506 LL_I3C_RequestRxFIFOFlush(hi3c->Instance);
8507 }
8508 }
8509
8510 /* I3C Abort frame complete event Check */
8511 /* Evenif abort is called, the Frame completion can arrive if abort is requested at the end of the processus */
8512 /* Evenif completion occurs, treat this end of processus as abort completion process */
8513 if (I3C_CHECK_FLAG(itMasks, I3C_EVR_FCF) != RESET)
8514 {
8515 /* Clear frame complete flag */
8516 LL_I3C_ClearFlag_FC(hi3c->Instance);
8517
8518 /* Call error treatment function */
8519 I3C_ErrorTreatment(hi3c);
8520 }
8521 }
8522 return HAL_OK;
8523 }
8524
8525 #if defined(HAL_DMA_MODULE_ENABLED)
8526 /**
8527 * @brief DMA I3C control transmit process complete callback.
8528 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8529 * for the specified DMA channel.
8530 * @retval None
8531 */
I3C_DMAControlTransmitCplt(DMA_HandleTypeDef * hdma)8532 static void I3C_DMAControlTransmitCplt(DMA_HandleTypeDef *hdma)
8533 {
8534 /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */
8535 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8536
8537 /* Disable control DMA Request */
8538 LL_I3C_DisableDMAReq_Control(hi3c->Instance);
8539 }
8540
8541 /**
8542 * @brief DMA I3C transmit data process complete callback.
8543 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8544 * for the specified DMA channel.
8545 * @retval None
8546 */
I3C_DMADataTransmitCplt(DMA_HandleTypeDef * hdma)8547 static void I3C_DMADataTransmitCplt(DMA_HandleTypeDef *hdma)
8548 {
8549 /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */
8550 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8551
8552 /* Disable Tx DMA Request */
8553 LL_I3C_DisableDMAReq_TX(hi3c->Instance);
8554 }
8555
8556 /**
8557 * @brief DMA I3C receive data process complete callback.
8558 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8559 * for the specified DMA channel.
8560 * @retval None
8561 */
I3C_DMADataReceiveCplt(DMA_HandleTypeDef * hdma)8562 static void I3C_DMADataReceiveCplt(DMA_HandleTypeDef *hdma)
8563 {
8564 /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */
8565 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8566
8567 /* Disable Rx DMA Request */
8568 LL_I3C_DisableDMAReq_RX(hi3c->Instance);
8569 }
8570
8571 /**
8572 * @brief DMA I3C communication error callback.
8573 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8574 * for the specified DMA channel.
8575 * @retval None
8576 */
I3C_DMAError(DMA_HandleTypeDef * hdma)8577 static void I3C_DMAError(DMA_HandleTypeDef *hdma)
8578 {
8579 /* Just to solve MisraC error then to be removed */
8580 /* Derogation MISRAC2012-Rule-11.5 */
8581 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8582
8583 hi3c->ErrorCode |= HAL_I3C_ERROR_DMA;
8584 }
8585
8586 /**
8587 * @brief DMA I3C communication abort callback to be called at end of DMA Abort procedure.
8588 * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information
8589 * for the specified DMA channel.
8590 * @retval None
8591 */
I3C_DMAAbort(DMA_HandleTypeDef * hdma)8592 static void I3C_DMAAbort(DMA_HandleTypeDef *hdma)
8593 {
8594 /* Derogation MISRAC2012-Rule-11.5 */
8595 I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
8596
8597 /* Reset Tx DMA AbortCpltCallback */
8598 if (hi3c->hdmatx != NULL)
8599 {
8600 hi3c->hdmatx->XferAbortCallback = NULL;
8601 }
8602
8603 /* Reset Rx DMA AbortCpltCallback */
8604 if (hi3c->hdmarx != NULL)
8605 {
8606 hi3c->hdmarx->XferAbortCallback = NULL;
8607 }
8608
8609 /* Reset control DMA AbortCpltCallback */
8610 if (hi3c->hdmacr != NULL)
8611 {
8612 hi3c->hdmacr->XferAbortCallback = NULL;
8613 }
8614
8615 I3C_TreatErrorCallback(hi3c);
8616 }
8617 #endif /* HAL_DMA_MODULE_ENABLED */
8618
8619 /**
8620 * @brief This function handles I3C Communication Timeout.
8621 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8622 * information for the specified I3C.
8623 * @param flag : [IN] Specifies the I3C flag to check.
8624 * @param flagstatus : [IN] The new Flag status (SET or RESET).
8625 * @param timeout : [IN] Timeout duration in millisecond.
8626 * @param tickstart : [IN] Tick start value
8627 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8628 */
I3C_WaitOnFlagUntilTimeout(I3C_HandleTypeDef * hi3c,uint32_t flag,FlagStatus flagstatus,uint32_t timeout,uint32_t tickstart)8629 static HAL_StatusTypeDef I3C_WaitOnFlagUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t flag, FlagStatus flagstatus,
8630 uint32_t timeout, uint32_t tickstart)
8631 {
8632 HAL_StatusTypeDef status = HAL_OK;
8633
8634 while ((__HAL_I3C_GET_FLAG(hi3c, flag) == flagstatus) && (status == HAL_OK))
8635 {
8636 /* Check for the Timeout */
8637 if (timeout != HAL_MAX_DELAY)
8638 {
8639 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
8640 {
8641 if (__HAL_I3C_GET_FLAG(hi3c, flag) == flagstatus)
8642 {
8643 hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT;
8644 status = HAL_TIMEOUT;
8645 }
8646 }
8647 }
8648
8649 /* Check if an error occurs during Flag waiting */
8650 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
8651 {
8652 /* Clear error flag */
8653 LL_I3C_ClearFlag_ERR(hi3c->Instance);
8654
8655 /* Update handle error code parameter */
8656 I3C_GetErrorSources(hi3c);
8657
8658 status = HAL_ERROR;
8659 }
8660 }
8661 return status;
8662 }
8663
8664 /**
8665 * @brief This function handles I3C Dynamic Address Assignment timeout.
8666 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8667 * information for the specified I3C.
8668 * @param timeout : [IN] Timeout duration in millisecond.
8669 * @param tickstart : [IN] Tick start value
8670 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8671 */
I3C_WaitOnDAAUntilTimeout(I3C_HandleTypeDef * hi3c,uint32_t timeout,uint32_t tickstart)8672 static HAL_StatusTypeDef I3C_WaitOnDAAUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t timeout, uint32_t tickstart)
8673 {
8674 HAL_StatusTypeDef status = HAL_OK;
8675 uint32_t active_flags = READ_REG(hi3c->Instance->EVR);
8676
8677 while (((active_flags & (HAL_I3C_FLAG_FCF | HAL_I3C_FLAG_TXFNFF)) == 0U) && (status == HAL_OK))
8678 {
8679 /* Check for the Timeout */
8680 if (timeout != HAL_MAX_DELAY)
8681 {
8682 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
8683 {
8684 if ((active_flags & (HAL_I3C_FLAG_FCF | HAL_I3C_FLAG_TXFNFF)) == 0U)
8685 {
8686 hi3c->ErrorCode |= HAL_I3C_ERROR_TIMEOUT;
8687 status = HAL_TIMEOUT;
8688 }
8689 }
8690 }
8691
8692 /* Check if an error occurs during Flag waiting */
8693 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET)
8694 {
8695 /* Clear error flag */
8696 LL_I3C_ClearFlag_ERR(hi3c->Instance);
8697
8698 /* Update handle error code parameter */
8699 I3C_GetErrorSources(hi3c);
8700
8701 status = HAL_ERROR;
8702 }
8703
8704 /* Read active flags from EVR register */
8705 active_flags = READ_REG(hi3c->Instance->EVR);
8706 }
8707 return status;
8708 }
8709
8710 /**
8711 * @brief I3C transmit by byte.
8712 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8713 * information for the specified I3C.
8714 * @retval None
8715 */
I3C_TransmitByteTreatment(I3C_HandleTypeDef * hi3c)8716 static void I3C_TransmitByteTreatment(I3C_HandleTypeDef *hi3c)
8717 {
8718 /* Check TX FIFO not full flag */
8719 while ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET) && (hi3c->TxXferCount > 0U))
8720 {
8721 /* Write Tx buffer data to transmit register */
8722 LL_I3C_TransmitData8(hi3c->Instance, *hi3c->pXferData->TxBuf.pBuffer);
8723
8724 /* Increment Buffer pointer */
8725 hi3c->pXferData->TxBuf.pBuffer++;
8726
8727 /* Decrement remaining bytes counter */
8728 hi3c->TxXferCount--;
8729 }
8730 }
8731
8732 /**
8733 * @brief I3C transmit by word.
8734 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8735 * information for the specified I3C.
8736 * @retval None
8737 */
I3C_TransmitWordTreatment(I3C_HandleTypeDef * hi3c)8738 static void I3C_TransmitWordTreatment(I3C_HandleTypeDef *hi3c)
8739 {
8740 /* Check TX FIFO not full flag */
8741 while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET)
8742 {
8743 /* Write Tx buffer data to transmit register */
8744 LL_I3C_TransmitData32(hi3c->Instance, *((uint32_t *)hi3c->pXferData->TxBuf.pBuffer));
8745
8746 /* Increment Buffer pointer */
8747 hi3c->pXferData->TxBuf.pBuffer += sizeof(uint32_t);
8748
8749 if (hi3c->TxXferCount < sizeof(uint32_t))
8750 {
8751 hi3c->TxXferCount = 0U;
8752 }
8753 else
8754 {
8755 /* Decrement remaining bytes counter */
8756 hi3c->TxXferCount -= sizeof(uint32_t);
8757 }
8758 }
8759 }
8760
8761 /**
8762 * @brief I3C receive by byte.
8763 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8764 * information for the specified I3C.
8765 * @retval None
8766 */
I3C_ReceiveByteTreatment(I3C_HandleTypeDef * hi3c)8767 static void I3C_ReceiveByteTreatment(I3C_HandleTypeDef *hi3c)
8768 {
8769 /* Check RX FIFO not empty flag */
8770 while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_RXFNEF) == SET)
8771 {
8772 /* Store received bytes in the Rx buffer */
8773 *hi3c->pXferData->RxBuf.pBuffer = LL_I3C_ReceiveData8(hi3c->Instance);
8774
8775 /* Increment Buffer pointer */
8776 hi3c->pXferData->RxBuf.pBuffer++;
8777
8778 /* Decrement remaining bytes counter */
8779 hi3c->RxXferCount--;
8780 }
8781 }
8782
8783 /**
8784 * @brief I3C receive by word.
8785 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8786 * information for the specified I3C.
8787 * @retval None
8788 */
I3C_ReceiveWordTreatment(I3C_HandleTypeDef * hi3c)8789 static void I3C_ReceiveWordTreatment(I3C_HandleTypeDef *hi3c)
8790 {
8791 /* Check RX FIFO not empty flag */
8792 while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_RXFNEF) == SET)
8793 {
8794 /* Store received bytes in the Rx buffer */
8795 *((uint32_t *)hi3c->pXferData->RxBuf.pBuffer) = LL_I3C_ReceiveData32(hi3c->Instance);
8796
8797 /* Increment Buffer pointer */
8798 hi3c->pXferData->RxBuf.pBuffer += sizeof(uint32_t);
8799
8800 if (hi3c->RxXferCount > sizeof(uint32_t))
8801 {
8802 /* Decrement remaining bytes counter */
8803 hi3c->RxXferCount -= sizeof(uint32_t);
8804 }
8805 else
8806 {
8807 /* Reset counter as last modulo word Rx data received */
8808 hi3c->RxXferCount = 0U;
8809 }
8810 }
8811 }
8812
8813 /**
8814 * @brief I3C Control data treatment.
8815 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8816 * information for the specified I3C.
8817 * @retval None
8818 */
I3C_ControlDataTreatment(I3C_HandleTypeDef * hi3c)8819 static void I3C_ControlDataTreatment(I3C_HandleTypeDef *hi3c)
8820 {
8821 /* Check if Control FIFO requests data */
8822 if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_CFNFF) == SET)
8823 {
8824 /* Decrement remaining control buffer data counter */
8825 hi3c->ControlXferCount--;
8826
8827 /* Write Control buffer data to control register */
8828 WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer);
8829
8830 /* Increment Buffer pointer */
8831 hi3c->pXferData->CtrlBuf.pBuffer++;
8832 }
8833 }
8834
8835 /**
8836 * @brief I3C state update.
8837 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8838 * information for the specified I3C.
8839 * @retval None
8840 */
I3C_StateUpdate(I3C_HandleTypeDef * hi3c)8841 static void I3C_StateUpdate(I3C_HandleTypeDef *hi3c)
8842 {
8843 /* Check on previous state */
8844 if (hi3c->PreviousState == HAL_I3C_STATE_LISTEN)
8845 {
8846 /* Set state to listen */
8847 hi3c->State = HAL_I3C_STATE_LISTEN;
8848
8849 /* Check the I3C mode */
8850 if (hi3c->Mode == HAL_I3C_MODE_TARGET)
8851 {
8852 /* Store the target event treatment function */
8853 hi3c->XferISR = I3C_Tgt_Event_ISR;
8854 }
8855 else
8856 {
8857 /* Store the controller event treatment function */
8858 hi3c->XferISR = I3C_Ctrl_Event_ISR;
8859 }
8860 }
8861 else
8862 {
8863 /* Set state to ready */
8864 hi3c->State = HAL_I3C_STATE_READY;
8865
8866 /* Reset XferISR */
8867 hi3c->XferISR = NULL;
8868 }
8869 }
8870
8871 /**
8872 * @brief I3C get error source.
8873 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8874 * information for the specified I3C.
8875 * @retval None
8876 */
I3C_GetErrorSources(I3C_HandleTypeDef * hi3c)8877 static void I3C_GetErrorSources(I3C_HandleTypeDef *hi3c)
8878 {
8879 /* Check on the I3C mode */
8880 switch (hi3c->Mode)
8881 {
8882 case HAL_I3C_MODE_CONTROLLER:
8883 {
8884 /* I3C data error during controller-role hand-off procedure */
8885 if (LL_I3C_IsActiveFlag_DERR(hi3c->Instance) == 1U)
8886 {
8887 hi3c->ErrorCode |= HAL_I3C_ERROR_DATA_HAND_OFF;
8888 }
8889
8890 /* I3C data not acknowledged error */
8891 if (LL_I3C_IsActiveFlag_DNACK(hi3c->Instance) == 1U)
8892 {
8893 hi3c->ErrorCode |= HAL_I3C_ERROR_DATA_NACK;
8894 }
8895
8896 /* I3C address not acknowledged error */
8897 if (LL_I3C_IsActiveFlag_ANACK(hi3c->Instance) == 1U)
8898 {
8899 hi3c->ErrorCode |= HAL_I3C_ERROR_ADDRESS_NACK;
8900 }
8901
8902 /* I3C Status FIFO Over-Run or Control FIFO Under-Run error */
8903 if (LL_I3C_IsActiveFlag_COVR(hi3c->Instance) == 1U)
8904 {
8905 hi3c->ErrorCode |= HAL_I3C_ERROR_COVR;
8906 }
8907
8908 break;
8909 }
8910
8911 case HAL_I3C_MODE_TARGET:
8912 {
8913 /* I3C SCL stall error */
8914 if (LL_I3C_IsActiveFlag_STALL(hi3c->Instance) == 1U)
8915 {
8916 hi3c->ErrorCode |= HAL_I3C_ERROR_STALL;
8917 }
8918
8919 break;
8920 }
8921
8922 default:
8923 {
8924 break;
8925 }
8926 }
8927
8928 /* I3C Rx FIFO Over-Run or Tx FIFO Under-Run error */
8929 if (LL_I3C_IsActiveFlag_DOVR(hi3c->Instance) == 1U)
8930 {
8931 hi3c->ErrorCode |= HAL_I3C_ERROR_DOVR;
8932 }
8933
8934 /* I3C Protocol error */
8935 if (LL_I3C_IsActiveFlag_PERR(hi3c->Instance) == 1U)
8936 {
8937 hi3c->ErrorCode |= (I3C_SER_PERR | LL_I3C_GetMessageErrorCode(hi3c->Instance));
8938 }
8939 }
8940
8941 /**
8942 * @brief I3C transfer prior preparation.
8943 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
8944 * information for the specified I3C.
8945 * @param counter : [IN] Number of devices or commands to treat.
8946 * @param option : [IN] Parameter indicates the transfer option.
8947 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
8948 */
I3C_Xfer_PriorPreparation(I3C_HandleTypeDef * hi3c,uint8_t counter,uint32_t option)8949 static HAL_StatusTypeDef I3C_Xfer_PriorPreparation(I3C_HandleTypeDef *hi3c, uint8_t counter, uint32_t option)
8950 {
8951 HAL_StatusTypeDef status = HAL_OK;
8952 uint32_t current_tx_index = 0U;
8953 uint32_t global_tx_size = 0U;
8954 uint32_t global_rx_size = 0U;
8955 uint32_t nb_tx_frame = 0U;
8956 uint32_t direction;
8957
8958 for (uint32_t descr_index = 0U; descr_index < counter; descr_index++)
8959 {
8960 /* Direct CCC command */
8961 if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT)
8962 {
8963 /* Update direction of frame */
8964 direction = hi3c->pCCCDesc[descr_index].Direction;
8965
8966 /* Direction read with Define byte */
8967 if (((option & I3C_DEFINE_BYTE_MASK) != 0U) && (direction == HAL_I3C_DIRECTION_READ))
8968 {
8969 nb_tx_frame += 1U;
8970
8971 global_tx_size += 1U;
8972
8973 global_rx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size - 1U;
8974
8975 /* Check on the global size and on the Tx buffer pointer */
8976 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
8977 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
8978 (hi3c->pXferData->TxBuf.pBuffer == NULL))
8979 {
8980 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
8981
8982 status = HAL_ERROR;
8983 }
8984 else
8985 {
8986 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
8987 current_tx_index = I3C_FillTxBuffer_CCC(hi3c, descr_index, 1U, current_tx_index);
8988 }
8989 }
8990 else if (direction == HAL_I3C_DIRECTION_WRITE)
8991 {
8992 nb_tx_frame += 1U;
8993
8994 global_tx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size;
8995
8996 /* Check on the global size and on the Tx buffer pointer */
8997 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
8998 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
8999 (hi3c->pXferData->TxBuf.pBuffer == NULL))
9000 {
9001 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9002
9003 status = HAL_ERROR;
9004 }
9005 else
9006 {
9007 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
9008 current_tx_index = I3C_FillTxBuffer_CCC(hi3c,
9009 descr_index,
9010 hi3c->pCCCDesc[descr_index].CCCBuf.Size,
9011 current_tx_index);
9012 }
9013 }
9014 /* Direction read without Define byte */
9015 else
9016 {
9017 global_rx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size;
9018 }
9019 }
9020 /* Broadcast CCC command */
9021 else if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC)
9022 {
9023 /* Update direction of frame */
9024 direction = hi3c->pCCCDesc[descr_index].Direction;
9025
9026 if (direction == HAL_I3C_DIRECTION_WRITE)
9027 {
9028 nb_tx_frame += 1U;
9029
9030 global_tx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size;
9031
9032 /* Check on the global size and on the Tx buffer pointer */
9033 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
9034 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
9035 (hi3c->pXferData->TxBuf.pBuffer == NULL))
9036 {
9037 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9038
9039 status = HAL_ERROR;
9040 }
9041 else
9042 {
9043 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
9044 current_tx_index = I3C_FillTxBuffer_CCC(hi3c,
9045 descr_index,
9046 hi3c->pCCCDesc[descr_index].CCCBuf.Size,
9047 current_tx_index);
9048 }
9049 }
9050 else
9051 {
9052 status = HAL_ERROR;
9053 }
9054 }
9055 /* Private */
9056 else
9057 {
9058 /* Update direction of frame */
9059 direction = hi3c->pPrivateDesc[descr_index].Direction;
9060
9061 if (direction == HAL_I3C_DIRECTION_WRITE)
9062 {
9063 nb_tx_frame += 1U;
9064
9065 global_tx_size += hi3c->pPrivateDesc[descr_index].TxBuf.Size;
9066
9067 /* Check on the global size and on the Tx buffer pointer */
9068 if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \
9069 (current_tx_index > hi3c->pXferData->TxBuf.Size) || \
9070 (hi3c->pXferData->TxBuf.pBuffer == NULL))
9071 {
9072 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9073
9074 status = HAL_ERROR;
9075 }
9076 else
9077 {
9078 /* Fill global Tx buffer with data and update the current index of the Tx buffer */
9079 current_tx_index = I3C_FillTxBuffer_Private(hi3c,
9080 descr_index,
9081 hi3c->pPrivateDesc[descr_index].TxBuf.Size,
9082 current_tx_index);
9083 }
9084 }
9085 else
9086 {
9087 global_rx_size += hi3c->pPrivateDesc[descr_index].RxBuf.Size;
9088 }
9089 }
9090
9091 /* Check if there is an error in the Tx Buffer*/
9092 if (status == HAL_ERROR)
9093 {
9094 break;
9095 }
9096 }
9097
9098 if (status == HAL_OK)
9099 {
9100 /* Check on the Tx threshold and the number of Tx frame */
9101 if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_4_4)
9102 {
9103 /* LL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains
9104 multiple transmission frames */
9105 if (nb_tx_frame > 1U)
9106 {
9107 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
9108 status = HAL_ERROR;
9109 }
9110 }
9111 }
9112
9113 if (status == HAL_OK)
9114 {
9115 /* Check on the size Rx buffer */
9116 if (global_rx_size > hi3c->pXferData->RxBuf.Size)
9117 {
9118 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9119 status = HAL_ERROR;
9120 }
9121 else
9122 {
9123 hi3c->RxXferCount = global_rx_size;
9124 }
9125
9126 /* Set handle transfer parameters */
9127 hi3c->TxXferCount = global_tx_size;
9128 }
9129
9130 return status;
9131 }
9132
9133 /**
9134 * @brief I3C fill Tx Buffer with data from CCC Descriptor.
9135 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9136 * information for the specified I3C.
9137 * @param indexDesc : [IN] Index of descriptor.
9138 * @param txSize : [IN] Size of Tx data.
9139 * @param txCurrentIndex : [IN] Current Index of TxBuffer.
9140 * @retval index_tx : [OUT] New current Index of TxBuffer.
9141 */
I3C_FillTxBuffer_CCC(I3C_HandleTypeDef * hi3c,uint32_t indexDesc,uint32_t txSize,uint32_t txCurrentIndex)9142 static uint32_t I3C_FillTxBuffer_CCC(I3C_HandleTypeDef *hi3c,
9143 uint32_t indexDesc,
9144 uint32_t txSize,
9145 uint32_t txCurrentIndex)
9146 {
9147 uint32_t index_tx = txCurrentIndex;
9148
9149 for (uint32_t index = 0U; index < txSize; index++)
9150 {
9151 hi3c->pXferData->TxBuf.pBuffer[index_tx] = hi3c->pCCCDesc[indexDesc].CCCBuf.pBuffer[index];
9152
9153 index_tx++;
9154 }
9155
9156 return index_tx;
9157 }
9158
9159 /**
9160 * @brief I3C fill Tx Buffer with data from Private Descriptor.
9161 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9162 * information for the specified I3C.
9163 * @param indexDesc : [IN] Index of descriptor.
9164 * @param txSize : [IN] Size of Tx data.
9165 * @param txCurrentIndex : [IN] Current Index of TxBuffer.
9166 * @retval index_tx : [OUT] New current Index of TxBuffer.
9167 */
I3C_FillTxBuffer_Private(I3C_HandleTypeDef * hi3c,uint32_t indexDesc,uint32_t txSize,uint32_t txCurrentIndex)9168 static uint32_t I3C_FillTxBuffer_Private(I3C_HandleTypeDef *hi3c,
9169 uint32_t indexDesc,
9170 uint32_t txSize,
9171 uint32_t txCurrentIndex)
9172 {
9173 uint32_t index_tx = txCurrentIndex;
9174
9175 for (uint32_t index = 0U; index < txSize; index++)
9176 {
9177 hi3c->pXferData->TxBuf.pBuffer[index_tx] = hi3c->pPrivateDesc[indexDesc].TxBuf.pBuffer[index];
9178
9179 index_tx++;
9180 }
9181
9182 return index_tx;
9183 }
9184
9185 /**
9186 * @brief I3C Control buffer prior preparation.
9187 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9188 * information for the specified I3C.
9189 * @param counter : [IN] Number of devices or commands to treat.
9190 * @param option : [IN] Parameter indicates the transfer option.
9191 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
9192 */
I3C_ControlBuffer_PriorPreparation(I3C_HandleTypeDef * hi3c,uint8_t counter,uint32_t option)9193 static HAL_StatusTypeDef I3C_ControlBuffer_PriorPreparation(I3C_HandleTypeDef *hi3c,
9194 uint8_t counter,
9195 uint32_t option)
9196 {
9197 HAL_StatusTypeDef status = HAL_OK;
9198 uint32_t nb_define_bytes;
9199 uint32_t stop_condition;
9200 uint32_t nb_data_bytes;
9201 uint32_t index;
9202
9203 /* Check on the control buffer pointer */
9204 if (hi3c->pXferData->CtrlBuf.pBuffer == NULL)
9205 {
9206 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9207 status = HAL_ERROR;
9208 }
9209 else
9210 {
9211 /* Extract from option required information */
9212 nb_define_bytes = (option & I3C_DEFINE_BYTE_MASK);
9213 stop_condition = (option & I3C_RESTART_STOP_MASK);
9214
9215 /* Check on the deactivation of the arbitration */
9216 if ((option & I3C_ARBITRATION_HEADER_MASK) == I3C_ARBITRATION_HEADER_MASK)
9217 {
9218 /* Disable arbitration header */
9219 LL_I3C_DisableArbitrationHeader(hi3c->Instance);
9220 }
9221 else
9222 {
9223 /* Enable arbitration header */
9224 LL_I3C_EnableArbitrationHeader(hi3c->Instance);
9225 }
9226
9227 /* Check on the operation type */
9228 if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC)
9229 {
9230 /*------------------------------------------ Broadcast CCC -----------------------------------------------------*/
9231 /* Check on the control buffer size */
9232 if (hi3c->pXferData->CtrlBuf.Size < (uint32_t)counter)
9233 {
9234 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9235 status = HAL_ERROR;
9236 }
9237 else
9238 {
9239 /* Set remaining control buffer data counter */
9240 hi3c->ControlXferCount = (uint32_t)counter;
9241
9242 /* For loop on the number of commands */
9243 for (index = 0U; index < ((uint32_t)counter - 1U); index++)
9244 {
9245 /* Update control buffer value */
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 | stop_condition);
9249 }
9250
9251 /* At the last device we should generate a stop condition */
9252 hi3c->pXferData->CtrlBuf.pBuffer[index] = ((uint32_t)hi3c->pCCCDesc[index].CCCBuf.Size |
9253 ((uint32_t)hi3c->pCCCDesc[index].CCC << I3C_CR_CCC_Pos) |
9254 LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_STOP);
9255 }
9256 }
9257 else if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT)
9258 {
9259 /*------------------------------------------ Direct CCC --------------------------------------------------------*/
9260 /* Check on the control buffer size */
9261 if (hi3c->pXferData->CtrlBuf.Size < ((uint32_t)counter * 2U))
9262 {
9263 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9264 status = HAL_ERROR;
9265 }
9266 else
9267 {
9268 /* Set remaining control buffer data counter */
9269 hi3c->ControlXferCount = ((uint32_t)counter * 2U);
9270
9271 /* For loop on the number of (devices or commands) * 2 */
9272 for (index = 0U; index < (((uint32_t)counter * 2U) - 2U); index += 2U)
9273 {
9274 /* Step 1 : update control buffer value for the CCC command */
9275 hi3c->pXferData->CtrlBuf.pBuffer[index] = (nb_define_bytes |
9276 ((uint32_t)hi3c->pCCCDesc[index / 2U].CCC << I3C_CR_CCC_Pos) |
9277 LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_RESTART);
9278
9279 /* Step 2 : update control buffer value for target address */
9280 hi3c->pXferData->CtrlBuf.pBuffer[index + 1U] =
9281 (((uint32_t)hi3c->pCCCDesc[index / 2U].CCCBuf.Size - nb_define_bytes) |
9282 hi3c->pCCCDesc[index / 2U].Direction |
9283 ((uint32_t)hi3c->pCCCDesc[index / 2U].TargetAddr << I3C_CR_ADD_Pos) |
9284 LL_I3C_CONTROLLER_MTYPE_DIRECT | stop_condition);
9285 }
9286
9287 /* Update control buffer value for the last CCC command */
9288 hi3c->pXferData->CtrlBuf.pBuffer[index] = (nb_define_bytes |
9289 ((uint32_t)hi3c->pCCCDesc[index / 2U].CCC << I3C_CR_CCC_Pos) |
9290 LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_RESTART);
9291
9292 /* At the last device we should generate a stop condition */
9293 hi3c->pXferData->CtrlBuf.pBuffer[index + 1U] =
9294 (((uint32_t)hi3c->pCCCDesc[index / 2U].CCCBuf.Size - nb_define_bytes) |
9295 hi3c->pCCCDesc[index / 2U].Direction |
9296 ((uint32_t)hi3c->pCCCDesc[index / 2U].TargetAddr << I3C_CR_ADD_Pos) |
9297 LL_I3C_CONTROLLER_MTYPE_DIRECT | LL_I3C_GENERATE_STOP);
9298 }
9299 }
9300 else
9301 {
9302 /*------------------------------------------ Private I3C/I2C ---------------------------------------------------*/
9303 /* Check on the control buffer size */
9304 if (hi3c->pXferData->CtrlBuf.Size < (uint32_t)counter)
9305 {
9306 hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM;
9307 status = HAL_ERROR;
9308 }
9309 else
9310 {
9311 /* Set remaining control buffer data counter */
9312 hi3c->ControlXferCount = (uint32_t)counter;
9313
9314 /* For loop on the number of devices */
9315 for (index = 0U; index < ((uint32_t)counter - 1U); index++)
9316 {
9317 /* Check on transfer direction */
9318 if (hi3c->pPrivateDesc[index].Direction == HAL_I3C_DIRECTION_READ)
9319 {
9320 nb_data_bytes = hi3c->pPrivateDesc[index].RxBuf.Size;
9321 }
9322 else
9323 {
9324 nb_data_bytes = hi3c->pPrivateDesc[index].TxBuf.Size;
9325 }
9326
9327 /* Update control buffer value */
9328 hi3c->pXferData->CtrlBuf.pBuffer[index] =
9329 (nb_data_bytes | hi3c->pPrivateDesc[index].Direction |
9330 ((uint32_t)hi3c->pPrivateDesc[index].TargetAddr << I3C_CR_ADD_Pos) |
9331 (option & I3C_OPERATION_TYPE_MASK) | stop_condition);
9332 }
9333
9334 /* Check on transfer direction */
9335 if (hi3c->pPrivateDesc[index].Direction == HAL_I3C_DIRECTION_READ)
9336 {
9337 nb_data_bytes = hi3c->pPrivateDesc[index].RxBuf.Size;
9338 }
9339 else
9340 {
9341 nb_data_bytes = hi3c->pPrivateDesc[index].TxBuf.Size;
9342 }
9343
9344 /* At the last device we should generate a stop condition */
9345 hi3c->pXferData->CtrlBuf.pBuffer[index] =
9346 (nb_data_bytes | hi3c->pPrivateDesc[index].Direction |
9347 ((uint32_t)hi3c->pPrivateDesc[index].TargetAddr << I3C_CR_ADD_Pos) |
9348 (option & I3C_OPERATION_TYPE_MASK) | LL_I3C_GENERATE_STOP);
9349 }
9350 }
9351 }
9352
9353 return status;
9354 }
9355
9356 /**
9357 * @brief Check if target device is ready for communication.
9358 * @param hi3c : Pointer to a I3C_HandleTypeDef structure that contains
9359 * the configuration information for the specified I3C.
9360 * @param pDevice : [IN] Structure to define the device address and the device type.
9361 * @param trials : [IN] Number of trials
9362 * @param timeout : [IN] Timeout duration
9363 * @retval HAL Status : Value from HAL_StatusTypeDef enumeration.
9364 */
I3C_Ctrl_IsDevice_Ready(I3C_HandleTypeDef * hi3c,const I3C_DeviceTypeDef * pDevice,uint32_t trials,uint32_t timeout)9365 static HAL_StatusTypeDef I3C_Ctrl_IsDevice_Ready(I3C_HandleTypeDef *hi3c,
9366 const I3C_DeviceTypeDef *pDevice,
9367 uint32_t trials,
9368 uint32_t timeout)
9369 {
9370 __IO uint32_t I3C_Trials = 0UL;
9371 __IO uint32_t exit_condition;
9372 uint32_t CR_tmp;
9373 uint32_t tickstart;
9374 HAL_StatusTypeDef status = HAL_OK;
9375 HAL_I3C_StateTypeDef handle_state;
9376 uint32_t arbitration_previous_state;
9377
9378 /* Get I3C handle state */
9379 handle_state = hi3c->State;
9380
9381 /* check on the Mode */
9382 if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)
9383 {
9384 hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
9385 status = HAL_ERROR;
9386 }
9387 /* check on the State */
9388 else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN))
9389 {
9390 status = HAL_BUSY;
9391 }
9392 else
9393 {
9394 /* Set handle transfer parameters */
9395 hi3c->ErrorCode = HAL_I3C_ERROR_NONE;
9396 hi3c->State = HAL_I3C_STATE_BUSY;
9397
9398 /* Before modify the arbitration, get the current arbitration state */
9399 arbitration_previous_state = LL_I3C_IsEnabledArbitrationHeader(hi3c->Instance);
9400
9401 /* Disable arbitration header */
9402 LL_I3C_DisableArbitrationHeader(hi3c->Instance);
9403
9404 CR_tmp = (HAL_I3C_DIRECTION_WRITE |
9405 ((uint32_t)pDevice->Address << I3C_CR_ADD_Pos) |
9406 pDevice->MessageType | LL_I3C_GENERATE_STOP);
9407
9408 do
9409 {
9410 /* Initiate a start condition by writing in the CR register */
9411 WRITE_REG(hi3c->Instance->CR, CR_tmp);
9412
9413 /* Calculate exit_condition value based on Frame complete and error flags */
9414 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
9415
9416 tickstart = HAL_GetTick();
9417
9418 while (exit_condition == 0U)
9419 {
9420 if (timeout != HAL_MAX_DELAY)
9421 {
9422 if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))
9423 {
9424 /* Update I3C error code */
9425 hi3c->ErrorCode |= HAL_I3C_ERROR_TIMEOUT;
9426 status = HAL_TIMEOUT;
9427
9428 break;
9429 }
9430 }
9431 /* Calculate exit_condition value based on Frame complete and error flags */
9432 exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF));
9433 }
9434
9435 if (status == HAL_OK)
9436 {
9437 /* Check if the FCF flag has been set */
9438 if (__HAL_I3C_GET_FLAG(hi3c, I3C_EVR_FCF) == SET)
9439 {
9440 /* Clear frame complete flag */
9441 LL_I3C_ClearFlag_FC(hi3c->Instance);
9442
9443 /* Device is ready */
9444 break;
9445 }
9446 else
9447 {
9448 /* Clear ERR flag */
9449 LL_I3C_ClearFlag_ERR(hi3c->Instance);
9450 }
9451 }
9452
9453 /* Increment Trials */
9454 I3C_Trials++;
9455
9456 } while ((I3C_Trials < trials) && (status == HAL_OK));
9457
9458 /* Device is not ready */
9459 if (trials == I3C_Trials)
9460 {
9461 hi3c->ErrorCode = HAL_I3C_ERROR_ADDRESS_NACK;
9462 status = HAL_ERROR;
9463 }
9464
9465 /* update state to Previous state */
9466 I3C_StateUpdate(hi3c);
9467
9468 /* Check if previous arbitration state is enabled */
9469 if (arbitration_previous_state == 1U)
9470 {
9471 LL_I3C_EnableArbitrationHeader(hi3c->Instance);
9472 }
9473 }
9474
9475 return status;
9476 }
9477
9478 /**
9479 * @brief Manage the enabling of Interrupts.
9480 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9481 * information for the specified I3C.
9482 * @param InterruptRequest : [IN] Value of the interrupt request
9483 * @retval None
9484 */
I3C_Enable_IRQ(I3C_HandleTypeDef * hi3c,uint32_t InterruptRequest)9485 static void I3C_Enable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest)
9486 {
9487 uint32_t tmpisr = 0U;
9488
9489 /* Check if requested interrupts are related to listening mode */
9490 if ((InterruptRequest & I3C_XFER_LISTEN_IT) != 0U)
9491 {
9492 tmpisr |= ((InterruptRequest & (~I3C_XFER_LISTEN_IT)) | HAL_I3C_IT_ERRIE);
9493 }
9494
9495 /* Check if requested interrupts are related to target transmit in IT mode */
9496 if ((InterruptRequest & I3C_XFER_TARGET_TX_IT) != 0U)
9497 {
9498 /* Enable frame complete, transmit FIFO not full and error interrupts */
9499 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9500 }
9501
9502 /* Check if requested interrupts are related to target receive in IT mode */
9503 if ((InterruptRequest & I3C_XFER_TARGET_RX_IT) != 0U)
9504 {
9505 /* Enable frame complete, receive FIFO not empty and error interrupts */
9506 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE) ;
9507 }
9508
9509 /* Check if requested interrupts are related to transmit/receive in DMA mode */
9510 if ((InterruptRequest & I3C_XFER_DMA) != 0U)
9511 {
9512 /* Enable frame complete and error interrupts */
9513 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_ERRIE);
9514 }
9515
9516 /* Check if requested interrupts are related to target hot join */
9517 if ((InterruptRequest & I3C_XFER_TARGET_HOTJOIN) != 0U)
9518 {
9519 /* Enable dynamic address update and error interrupts */
9520 tmpisr |= (HAL_I3C_IT_DAUPDIE | HAL_I3C_IT_ERRIE);
9521 }
9522
9523 /* Check if requested interrupts are related to target control role */
9524 if ((InterruptRequest & I3C_XFER_TARGET_CTRLROLE) != 0U)
9525 {
9526 /* Enable control role update and error interrupts */
9527 tmpisr |= (HAL_I3C_IT_CRUPDIE | HAL_I3C_IT_ERRIE);
9528 }
9529
9530 /* Check if requested interrupts are related to target in band interrupt */
9531 if ((InterruptRequest & I3C_XFER_TARGET_IBI) != 0U)
9532 {
9533 /* Enable IBI end and error interrupts */
9534 tmpisr |= (HAL_I3C_IT_IBIENDIE | HAL_I3C_IT_ERRIE);
9535 }
9536
9537 /* Check if requested interrupts are related to controller transmit in IT mode */
9538 if ((InterruptRequest & I3C_XFER_CONTROLLER_TX_IT) != 0U)
9539 {
9540 /* Enable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9541 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9542 }
9543
9544 /* Check if requested interrupts are related to controller receive in IT mode */
9545 if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_IT) != 0U)
9546 {
9547 /* Enable frame complete, control FIFO not full, receive FIFO not empty and error interrupts */
9548 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9549 }
9550
9551 /* Check if requested interrupts are related to controller transmit read or a broadcast CCC in IT mode */
9552 if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_CCC_IT) != 0U)
9553 {
9554 /* Enable frame complete, transmit FIFO not full, control FIFO not full,
9555 receive FIFO not empty and error interrupts */
9556 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9557 }
9558
9559 /* Check if requested interrupts are related to controller transmit broadcast ENTDAA CCC in IT mode */
9560 if ((InterruptRequest & I3C_XFER_CONTROLLER_DAA_IT) != 0U)
9561 {
9562 /* Enable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9563 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9564 }
9565
9566 /* Enable requested interrupts */
9567 __HAL_I3C_ENABLE_IT(hi3c, tmpisr);
9568 }
9569
9570 /**
9571 * @brief Manage the disabling of Interrupts.
9572 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9573 * information for the specified I3C.
9574 * @param InterruptRequest : [IN] Value of the interrupt request
9575 * @retval None
9576 */
I3C_Disable_IRQ(I3C_HandleTypeDef * hi3c,uint32_t InterruptRequest)9577 static void I3C_Disable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest)
9578 {
9579 uint32_t tmpisr = 0U;
9580
9581 /* Check if requested interrupts are related to listening mode */
9582 if ((InterruptRequest & I3C_XFER_LISTEN_IT) != 0U)
9583 {
9584 tmpisr |= ((InterruptRequest & (~I3C_XFER_LISTEN_IT)) | HAL_I3C_IT_ERRIE);
9585 }
9586
9587 /* Check if requested interrupts are related to target transmit mode */
9588 if ((InterruptRequest & I3C_XFER_TARGET_TX_IT) != 0U)
9589 {
9590 /* Disable frame complete, transmit FIFO not full and error interrupts */
9591 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9592 }
9593
9594 /* Check if requested interrupts are related to target receive mode */
9595 if ((InterruptRequest & I3C_XFER_TARGET_RX_IT) != 0U)
9596 {
9597 /* Disable frame complete, receive FIFO not empty and error interrupts */
9598 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9599 }
9600
9601 /* Check if requested interrupts are related to transmit/receive in DMA mode */
9602 if ((InterruptRequest & I3C_XFER_DMA) != 0U)
9603 {
9604 /* Disable frame complete and error interrupts */
9605 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_ERRIE);
9606 }
9607
9608 /* Check if requested interrupts are related to target hot join */
9609 if ((InterruptRequest & I3C_XFER_TARGET_HOTJOIN) != 0U)
9610 {
9611 /* Disable dynamic address update and error interrupts */
9612 tmpisr |= (HAL_I3C_IT_DAUPDIE | HAL_I3C_IT_ERRIE);
9613 }
9614
9615 /* Check if requested interrupts are related to target control role */
9616 if ((InterruptRequest & I3C_XFER_TARGET_CTRLROLE) != 0U)
9617 {
9618 /* Disable control role update and error interrupts */
9619 tmpisr |= (HAL_I3C_IT_CRUPDIE | HAL_I3C_IT_ERRIE);
9620 }
9621
9622 /* Check if requested interrupts are related to target in band interrupt */
9623 if ((InterruptRequest & I3C_XFER_TARGET_IBI) != 0U)
9624 {
9625 /* Disable IBI end and error interrupts */
9626 tmpisr |= (HAL_I3C_IT_IBIENDIE | HAL_I3C_IT_ERRIE);
9627 }
9628
9629 /* Check if requested interrupts are related to controller transmit in IT mode */
9630 if ((InterruptRequest & I3C_XFER_CONTROLLER_TX_IT) != 0U)
9631 {
9632 /* Disable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9633 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9634 }
9635
9636 /* Check if requested interrupts are related to controller transmit read or a broadcast CCC in IT mode */
9637 if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_CCC_IT) != 0U)
9638 {
9639 /* Disable frame complete, transmit FIFO not full, control FIFO not full,
9640 receive FIFO not empty and error interrupts */
9641 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE);
9642 }
9643
9644 /* Check if requested interrupts are related to controller transmit broadcast ENTDAA CCC in IT mode */
9645 if ((InterruptRequest & I3C_XFER_CONTROLLER_DAA_IT) != 0U)
9646 {
9647 /* Disable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */
9648 tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE);
9649 }
9650
9651 /* Disable requested interrupts */
9652 __HAL_I3C_DISABLE_IT(hi3c, tmpisr);
9653 }
9654
9655 /**
9656 * @brief I3C error treatment.
9657 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9658 * information for the specified I3C.
9659 * @retval None
9660 */
I3C_ErrorTreatment(I3C_HandleTypeDef * hi3c)9661 static void I3C_ErrorTreatment(I3C_HandleTypeDef *hi3c)
9662 {
9663 HAL_I3C_StateTypeDef tmpstate = hi3c->State;
9664 uint32_t dmaabortongoing = 0U;
9665
9666 /* Check on the state */
9667 if (tmpstate == HAL_I3C_STATE_BUSY)
9668 {
9669 /* Update handle state parameter */
9670 I3C_StateUpdate(hi3c);
9671
9672 /* Disable all interrupts related to busy state */
9673 I3C_Disable_IRQ(hi3c, (I3C_XFER_TARGET_IBI | I3C_XFER_TARGET_HOTJOIN | I3C_XFER_TARGET_CTRLROLE));
9674 }
9675 else
9676 {
9677 /* Disable all interrupts related to busy Tx and Rx state */
9678 I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT);
9679
9680 /* Reset Tx counter */
9681 hi3c->TxXferCount = 0U;
9682
9683 /* Reset Rx counter */
9684 hi3c->RxXferCount = 0U;
9685
9686 /* Reset Control counter */
9687 hi3c->ControlXferCount = 0U;
9688
9689 /* Reset Tx function pointer */
9690 hi3c->ptrTxFunc = NULL;
9691
9692 /* Reset Rx function pointer */
9693 hi3c->ptrRxFunc = NULL;
9694
9695 /* Reset Context pointer */
9696 hi3c->pXferData = NULL;
9697 hi3c->pCCCDesc = NULL;
9698 hi3c->pPrivateDesc = NULL;
9699
9700 /* Flush all FIFOs */
9701 /* Flush the content of Tx Fifo */
9702 LL_I3C_RequestTxFIFOFlush(hi3c->Instance);
9703
9704 /* Flush the content of Rx Fifo */
9705 LL_I3C_RequestRxFIFOFlush(hi3c->Instance);
9706
9707 /* Check on the I3C mode: Control and status FIFOs available only with controller mode */
9708 if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER)
9709 {
9710 /* Flush the content of Control Fifo */
9711 LL_I3C_RequestControlFIFOFlush(hi3c->Instance);
9712
9713 /* Flush the content of Status Fifo */
9714 LL_I3C_RequestStatusFIFOFlush(hi3c->Instance);
9715 }
9716
9717 #if defined(HAL_DMA_MODULE_ENABLED)
9718 /* Abort control DMA transfer if any */
9719 if (hi3c->hdmacr != NULL)
9720 {
9721 /* Disable control DMA Request */
9722 LL_I3C_DisableDMAReq_Control(hi3c->Instance);
9723
9724 /* Check DMA state */
9725 if (HAL_DMA_GetState(hi3c->hdmacr) != HAL_DMA_STATE_READY)
9726 {
9727 /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback()
9728 at end of DMA abort procedure */
9729
9730 /* DMA abort on going */
9731 dmaabortongoing = 1U;
9732
9733 /* Abort control DMA */
9734 if (HAL_DMA_Abort_IT(hi3c->hdmacr) != HAL_OK)
9735 {
9736 /* Call Directly XferAbortCallback function in case of error */
9737 hi3c->hdmacr->XferAbortCallback(hi3c->hdmacr);
9738 }
9739 }
9740 }
9741
9742 /* Abort RX DMA transfer if any */
9743 if (hi3c->hdmarx != NULL)
9744 {
9745 /* Disable Rx DMA Request */
9746 LL_I3C_DisableDMAReq_RX(hi3c->Instance);
9747
9748 /* Check DMA state */
9749 if (HAL_DMA_GetState(hi3c->hdmarx) != HAL_DMA_STATE_READY)
9750 {
9751 /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback()
9752 at end of DMA abort procedure */
9753 hi3c->hdmarx->XferAbortCallback = I3C_DMAAbort;
9754
9755 /* DMA abort on going */
9756 dmaabortongoing = 1U;
9757
9758 /* Abort DMA RX */
9759 if (HAL_DMA_Abort_IT(hi3c->hdmarx) != HAL_OK)
9760 {
9761 /* Call Directly XferAbortCallback function in case of error */
9762 hi3c->hdmarx->XferAbortCallback(hi3c->hdmarx);
9763 }
9764 }
9765 }
9766
9767 /* Abort TX DMA transfer if any */
9768 if (hi3c->hdmatx != NULL)
9769 {
9770 /* Disable Tx DMA Request */
9771 LL_I3C_DisableDMAReq_TX(hi3c->Instance);
9772
9773 /* Check DMA state */
9774 if (HAL_DMA_GetState(hi3c->hdmatx) != HAL_DMA_STATE_READY)
9775 {
9776 /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback()
9777 at end of DMA abort procedure */
9778 hi3c->hdmatx->XferAbortCallback = I3C_DMAAbort;
9779
9780 /* DMA abort on going */
9781 dmaabortongoing = 1U;
9782
9783 /* Abort DMA TX */
9784 if (HAL_DMA_Abort_IT(hi3c->hdmatx) != HAL_OK)
9785 {
9786 /* Call Directly XferAbortCallback function in case of error */
9787 hi3c->hdmatx->XferAbortCallback(hi3c->hdmatx);
9788 }
9789 }
9790 }
9791 #endif /* HAL_DMA_MODULE_ENABLED */
9792 }
9793
9794 /* Call Error callback if there is no DMA abort on going */
9795 if (dmaabortongoing == 0U)
9796 {
9797 I3C_TreatErrorCallback(hi3c);
9798 }
9799 }
9800
9801 /**
9802 * @brief I3C Error callback treatment.
9803 * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration
9804 * information for the specified I3C.
9805 * @retval None
9806 */
I3C_TreatErrorCallback(I3C_HandleTypeDef * hi3c)9807 static void I3C_TreatErrorCallback(I3C_HandleTypeDef *hi3c)
9808 {
9809 if (hi3c->State == HAL_I3C_STATE_ABORT)
9810 {
9811 /* Update handle state parameter */
9812 I3C_StateUpdate(hi3c);
9813
9814 /* Call the corresponding callback to inform upper layer of End of Transfer */
9815 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1)
9816 hi3c->AbortCpltCallback(hi3c);
9817 #else
9818 HAL_I3C_AbortCpltCallback(hi3c);
9819 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
9820 }
9821 else
9822 {
9823 /* Update handle state parameter */
9824 I3C_StateUpdate(hi3c);
9825
9826 /* Call the corresponding callback to inform upper layer of End of Transfer */
9827 #if (USE_HAL_I3C_REGISTER_CALLBACKS == 1)
9828 hi3c->ErrorCallback(hi3c);
9829 #else
9830 HAL_I3C_ErrorCallback(hi3c);
9831 #endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
9832 }
9833 }
9834
9835 /**
9836 * @}
9837 */
9838
9839 #endif /* HAL_I3C_MODULE_ENABLED */
9840
9841 /**
9842 * @}
9843 */
9844
9845 /**
9846 * @}
9847 */
9848