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