1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_ll_i3c.c
4   * @author  MCD Application Team
5   * @brief   I3C LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2022 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 #if defined(USE_FULL_LL_DRIVER)
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32h5xx_ll_i3c.h"
22 #include "stm32h5xx_ll_bus.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28 
29 /** @addtogroup STM32H5xx_LL_Driver
30   * @{
31   */
32 
33 #if defined (I3C1)
34 
35 /** @defgroup I3C_LL I3C
36   * @{
37   */
38 
39 /* Private types -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private constants ---------------------------------------------------------*/
42 /* Private macros ------------------------------------------------------------*/
43 /** @addtogroup I3C_LL_Private_Macros
44   * @{
45   */
46 #define IS_LL_I3C_SDAHOLDTIME_VALUE(VALUE) (((VALUE) == LL_I3C_SDA_HOLD_TIME_0_5) || \
47                                             ((VALUE) == LL_I3C_SDA_HOLD_TIME_1_5))
48 
49 #define IS_LL_I3C_WAITTIME_VALUE(VALUE) (((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_0) || \
50                                          ((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_1) || \
51                                          ((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_2) || \
52                                          ((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_3))
53 /**
54   * @}
55   */
56 
57 /* Private function prototypes -----------------------------------------------*/
58 
59 /* Exported functions --------------------------------------------------------*/
60 /** @addtogroup I3C_LL_Exported_Functions
61   * @{
62   */
63 
64 /** @addtogroup I3C_LL_EF_Init
65   * @{
66   */
67 
68 /**
69   * @brief  De-initialize the I3C registers to their default reset values.
70   * @param  I3Cx I3C Instance.
71   * @retval An ErrorStatus enumeration value:
72   *          - SUCCESS: I3C registers are de-initialized
73   *          - ERROR: I3C registers are not de-initialized
74   */
LL_I3C_DeInit(I3C_TypeDef * I3Cx)75 ErrorStatus LL_I3C_DeInit(I3C_TypeDef *I3Cx)
76 {
77   ErrorStatus status = SUCCESS;
78 
79   /* Check the I3C Instance I3Cx */
80   assert_param(IS_I3C_ALL_INSTANCE(I3Cx));
81 
82   if (I3Cx == I3C1)
83   {
84     /* Force reset of I3C clock */
85     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I3C1);
86 
87     /* Release reset of I3C clock */
88     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I3C1);
89   }
90 #if defined(I3C2)
91   else if (I3Cx == I3C2)
92   {
93     /* Force reset of I3C clock */
94     LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_I3C2);
95 
96     /* Release reset of I3C clock */
97     LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_I3C2);
98 
99   }
100 #endif /* I3C2 */
101   else
102   {
103     status = ERROR;
104   }
105 
106   return status;
107 }
108 
109 /**
110   * @brief  Initialize the I3C registers according to the specified parameters in I3C_InitStruct.
111   * @param  I3Cx I3C Instance.
112   * @param  I3C_InitStruct pointer to a @ref LL_I3C_InitTypeDef structure.
113   * @param  Mode I3C peripheral mode.
114   *              This parameter can be a value of @ref I3C_LL_EC_MODE.
115   * @retval An ErrorStatus enumeration value:
116   *          - SUCCESS: I3C registers are initialized
117   *          - ERROR: Not applicable
118   */
LL_I3C_Init(I3C_TypeDef * I3Cx,LL_I3C_InitTypeDef * I3C_InitStruct,uint32_t Mode)119 ErrorStatus LL_I3C_Init(I3C_TypeDef *I3Cx, LL_I3C_InitTypeDef *I3C_InitStruct, uint32_t Mode)
120 {
121   uint32_t waveform_value;
122   uint32_t timing_value;
123 
124   /* Check the I3C Instance I3Cx */
125   assert_param(IS_I3C_ALL_INSTANCE(I3Cx));
126 
127   /* Disable the selected I3C peripheral */
128   LL_I3C_Disable(I3Cx);
129 
130   /* Check on the I3C mode: initialization depends on the mode */
131   if (Mode == LL_I3C_MODE_CONTROLLER)
132   {
133     /* Check the parameters */
134     assert_param(IS_LL_I3C_SDAHOLDTIME_VALUE(I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime));
135     assert_param(IS_LL_I3C_WAITTIME_VALUE(I3C_InitStruct->CtrlBusCharacteristic.WaitTime));
136 
137     /* Set Controller mode */
138     LL_I3C_SetMode(I3Cx, LL_I3C_MODE_CONTROLLER);
139 
140     /*------------------ SCL signal waveform configuration : I3C timing register 0 (I3C_TIMINGR0) ------------------- */
141     /* Set the controller SCL waveform */
142     waveform_value =
143       ((uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.SCLPPLowDuration)                                |
144        ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLI3CHighDuration << I3C_TIMINGR0_SCLH_I3C_Pos) |
145        ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLODLowDuration << I3C_TIMINGR0_SCLL_OD_Pos)    |
146        ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLI2CHighDuration << I3C_TIMINGR0_SCLH_I2C_Pos));
147 
148     LL_I3C_ConfigClockWaveForm(I3Cx, waveform_value);
149 
150     /*------------------- Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------- */
151     /* Set SDA hold time, activity state, bus free duration and bus available duration */
152     timing_value = ((uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime)                               |
153                     (uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.WaitTime)                                  |
154                     ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.BusFreeDuration <<  I3C_TIMINGR1_FREE_Pos) |
155                     (uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.BusIdleDuration));
156 
157     LL_I3C_SetCtrlBusCharacteristic(I3Cx, timing_value);
158   }
159   else
160   {
161     /* Set target mode */
162     LL_I3C_SetMode(I3Cx, LL_I3C_MODE_TARGET);
163 
164     /*------------------- Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------- */
165     /* Set the number of kernel clocks cycles for the bus available condition time */
166     LL_I3C_SetTgtBusCharacteristic(I3Cx, I3C_InitStruct->TgtBusCharacteristic.BusAvailableDuration);
167   }
168 
169   /* Enable the selected I3C peripheral */
170   LL_I3C_Enable(I3Cx);
171 
172   return SUCCESS;
173 }
174 
175 /**
176   * @brief  Set each @ref LL_I3C_InitTypeDef field to default value.
177   * @param  I3C_InitStruct Pointer to a @ref LL_I3C_InitTypeDef structure.
178   * @retval None
179   */
LL_I3C_StructInit(LL_I3C_InitTypeDef * I3C_InitStruct)180 void LL_I3C_StructInit(LL_I3C_InitTypeDef *I3C_InitStruct)
181 {
182   /* Set I3C_InitStruct fields to default values */
183   I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime         = LL_I3C_SDA_HOLD_TIME_0_5;
184   I3C_InitStruct->CtrlBusCharacteristic.WaitTime            = LL_I3C_OWN_ACTIVITY_STATE_0;
185   I3C_InitStruct->CtrlBusCharacteristic.SCLPPLowDuration    = 0U;
186   I3C_InitStruct->CtrlBusCharacteristic.SCLI3CHighDuration  = 0U;
187   I3C_InitStruct->CtrlBusCharacteristic.SCLODLowDuration    = 0U;
188   I3C_InitStruct->CtrlBusCharacteristic.SCLI2CHighDuration  = 0U;
189   I3C_InitStruct->CtrlBusCharacteristic.BusFreeDuration     = 0U;
190   I3C_InitStruct->CtrlBusCharacteristic.BusIdleDuration     = 0U;
191   I3C_InitStruct->TgtBusCharacteristic.BusAvailableDuration = 0U;
192 }
193 
194 /**
195   * @}
196   */
197 
198 /**
199   * @}
200   */
201 
202 /**
203   * @}
204   */
205 
206 #endif /* I3C1 */
207 
208 /**
209   * @}
210   */
211 
212 #endif /* USE_FULL_LL_DRIVER */
213