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