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