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