1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_ll_i3c.c
4   * @author  MCD Application Team
5   * @brief   I3C LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2023 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 "stm32n6xx_ll_bus.h"
22 #include "stm32n6xx_ll_i3c.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 STM32N6xx_LL_Driver
30   * @{
31   */
32 
33 #if defined (I3C1) || defined (I3C2)
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(const I3C_TypeDef * I3Cx)75 ErrorStatus LL_I3C_DeInit(const 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   else if (I3Cx == I3C2)
91   {
92     /* Force reset of I3C clock */
93     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I3C2);
94 
95     /* Release reset of I3C clock */
96     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I3C2);
97 
98   }
99   else
100   {
101     status = ERROR;
102   }
103 
104   return status;
105 }
106 
107 /**
108   * @brief  Initialize the I3C registers according to the specified parameters in I3C_InitStruct.
109   * @param  I3Cx I3C Instance.
110   * @param  I3C_InitStruct pointer to a @ref LL_I3C_InitTypeDef structure.
111   * @param  Mode I3C peripheral mode.
112   *              This parameter can be a value of @ref I3C_LL_EC_MODE.
113   * @retval An ErrorStatus enumeration value:
114   *          - SUCCESS: I3C registers are initialized
115   *          - ERROR: Not applicable
116   */
LL_I3C_Init(I3C_TypeDef * I3Cx,LL_I3C_InitTypeDef * I3C_InitStruct,uint32_t Mode)117 ErrorStatus LL_I3C_Init(I3C_TypeDef *I3Cx, LL_I3C_InitTypeDef *I3C_InitStruct, uint32_t Mode)
118 {
119   uint32_t waveform_value;
120   uint32_t timing_value;
121 
122   /* Check the I3C Instance I3Cx */
123   assert_param(IS_I3C_ALL_INSTANCE(I3Cx));
124 
125   /* Disable the selected I3C peripheral */
126   LL_I3C_Disable(I3Cx);
127 
128   /* Check on the I3C mode: initialization depends on the mode */
129   if (Mode == LL_I3C_MODE_CONTROLLER)
130   {
131     /* Check the parameters */
132     assert_param(IS_LL_I3C_SDAHOLDTIME_VALUE(I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime));
133     assert_param(IS_LL_I3C_WAITTIME_VALUE(I3C_InitStruct->CtrlBusCharacteristic.WaitTime));
134 
135     /* Set Controller mode */
136     LL_I3C_SetMode(I3Cx, LL_I3C_MODE_CONTROLLER);
137 
138     /*------------------ SCL signal waveform configuration : I3C timing register 0 (I3C_TIMINGR0) ------------------- */
139     /* Set the controller SCL waveform */
140     waveform_value =
141       ((uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.SCLPPLowDuration)                                |
142        ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLI3CHighDuration << I3C_TIMINGR0_SCLH_I3C_Pos) |
143        ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLODLowDuration << I3C_TIMINGR0_SCLL_OD_Pos)    |
144        ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLI2CHighDuration << I3C_TIMINGR0_SCLH_I2C_Pos));
145 
146     LL_I3C_ConfigClockWaveForm(I3Cx, waveform_value);
147 
148     /*------------------- Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------- */
149     /* Set SDA hold time, activity state, bus free duration and bus available duration */
150     timing_value = ((uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime)                               |
151                     (uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.WaitTime)                                  |
152                     ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.BusFreeDuration <<  I3C_TIMINGR1_FREE_Pos) |
153                     (uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.BusIdleDuration));
154 
155     LL_I3C_SetCtrlBusCharacteristic(I3Cx, timing_value);
156   }
157   else
158   {
159     /* Set target mode */
160     LL_I3C_SetMode(I3Cx, LL_I3C_MODE_TARGET);
161 
162     /*------------------- Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------- */
163     /* Set the number of kernel clocks cycles for the bus available condition time */
164     LL_I3C_SetTgtBusCharacteristic(I3Cx, I3C_InitStruct->TgtBusCharacteristic.BusAvailableDuration);
165   }
166 
167   /* Enable the selected I3C peripheral */
168   LL_I3C_Enable(I3Cx);
169 
170   return SUCCESS;
171 }
172 
173 /**
174   * @brief  Set each @ref LL_I3C_InitTypeDef field to default value.
175   * @param  I3C_InitStruct Pointer to a @ref LL_I3C_InitTypeDef structure.
176   * @retval None
177   */
LL_I3C_StructInit(LL_I3C_InitTypeDef * I3C_InitStruct)178 void LL_I3C_StructInit(LL_I3C_InitTypeDef *I3C_InitStruct)
179 {
180   /* Set I3C_InitStruct fields to default values */
181   I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime         = LL_I3C_SDA_HOLD_TIME_0_5;
182   I3C_InitStruct->CtrlBusCharacteristic.WaitTime            = LL_I3C_OWN_ACTIVITY_STATE_0;
183   I3C_InitStruct->CtrlBusCharacteristic.SCLPPLowDuration    = 0U;
184   I3C_InitStruct->CtrlBusCharacteristic.SCLI3CHighDuration  = 0U;
185   I3C_InitStruct->CtrlBusCharacteristic.SCLODLowDuration    = 0U;
186   I3C_InitStruct->CtrlBusCharacteristic.SCLI2CHighDuration  = 0U;
187   I3C_InitStruct->CtrlBusCharacteristic.BusFreeDuration     = 0U;
188   I3C_InitStruct->CtrlBusCharacteristic.BusIdleDuration     = 0U;
189   I3C_InitStruct->TgtBusCharacteristic.BusAvailableDuration = 0U;
190 }
191 
192 /**
193   * @}
194   */
195 
196 /**
197   * @}
198   */
199 
200 /**
201   * @}
202   */
203 
204 #endif /* I3C1 || I3C2 */
205 
206 /**
207   * @}
208   */
209 
210 #endif /* USE_FULL_LL_DRIVER */
211