1 /**
2 ******************************************************************************
3 * @file stsafe_service_stub.c
4 * @author MCD Application Team
5 * @version V1.0.0
6 * @brief Implementation file of psa_drv_se interface.
7 ******************************************************************************
8 * @attention
9 *
10 * <h2><center>© Copyright (c) 2021 STMicroelectronics.
11 * All rights reserved.</center></h2>
12 *
13 * This software component is licensed by ST under BSD 3-Clause license,
14 * the "License"; You may not use this file except in compliance with the
15 * License. You may obtain a copy of the License at:
16 * opensource.org/licenses/BSD-3-Clause
17 *
18 ******************************************************************************
19 */
20
21 /* Includes ------------------------------------------------------------------*/
22 #include "stm32u5xx.h"
23
24 /* Private typedef -----------------------------------------------------------*/
25 /* Private define ------------------------------------------------------------*/
26
27 #define STSAFEA_VREG_PIN GPIO_PIN_11
28 #define STSAFEA_VREG_GPIO_PORT GPIOF
29 #define STSAFEA_VREG_GPIO_PORT_CLK_ENABLE __HAL_RCC_GPIOF_CLK_ENABLE
30 #define STSAFEA_DEVICE_ADDRESS 0x0020
31
32 #define I2C_ANALOG_FILTER_DELAY_DEFAULT 2U /* ns */
33
34 #define BUS_I2C2_INSTANCE I2C2
35
36 #define BUS_I2C2_CLK_ENABLE() __HAL_RCC_I2C2_CLK_ENABLE()
37 #define BUS_I2C2_CLK_DISABLE() __HAL_RCC_I2C2_CLK_DISABLE()
38
39 #define BUS_I2C2_SDA_GPIO_PIN GPIO_PIN_5
40 #define BUS_I2C2_SCL_GPIO_PIN GPIO_PIN_4
41
42 #define BUS_I2C2_SDA_GPIO_PORT GPIOH
43 #define BUS_I2C2_SCL_GPIO_PORT GPIOH
44
45 #define BUS_I2C2_SDA_GPIO_AF GPIO_AF4_I2C2
46 #define BUS_I2C2_SCL_GPIO_AF GPIO_AF4_I2C2
47
48 #define BUS_I2C2_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
49 #define BUS_I2C2_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
50
51 #define BUS_I2C2_POLL_TIMEOUT 0x1000U
52
53 #define BUS_I2C2_TIMING 0x00F07BFF /* Corresponding to frequency of I2C1 = 400 KHz*/
54
55 /* Private macro -------------------------------------------------------------*/
56 /* Private variables ---------------------------------------------------------*/
57 I2C_HandleTypeDef hi2c2;
58 I2C_HandleTypeDef *hbus_i2c = &hi2c2;
59
60 /* Private function prototypes -----------------------------------------------*/
61 int32_t HW_IO_Init(void);
62 void BSP_TimeDelay(uint32_t msDelay);
63 HAL_StatusTypeDef MX_I2C2_Init(I2C_HandleTypeDef *phi2c, uint32_t timing);
64 int32_t BSP_I2C_Init(void);
65 int32_t BSP_I2C_DeInit(void);
66 int32_t BSP_I2C_Send(uint16_t DevAddr, uint8_t *pData, uint16_t Length);
67 int32_t BSP_I2C_Recv(uint16_t DevAddr, uint8_t *pData, uint16_t Length);
68 static void I2C2_MspInit(I2C_HandleTypeDef *hI2c);
69 static void I2C2_MspDeInit(I2C_HandleTypeDef *hI2c);
70 #define BSP_OK 0
71 #define BSP_NAK 1
72 #define BSP_ERROR -1
73
74 /* Private functions ---------------------------------------------------------*/
75
76
77 /**
78 * @brief Additional IO pins configuration needed for STSAFE (VREG pin, etc.)
79 * @param none
80 * @retval 0 in case of success, an error code otherwise
81 */
HW_IO_Init(void)82 int32_t HW_IO_Init(void)
83 {
84 GPIO_InitTypeDef GPIO_InitStruct;
85
86 /* GPIO Ports Clock Enable */
87 STSAFEA_VREG_GPIO_PORT_CLK_ENABLE();
88
89 /* Configure GPIO pin : RST Pin */
90 GPIO_InitStruct.Pin = STSAFEA_VREG_PIN;
91 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
92 GPIO_InitStruct.Pull = GPIO_NOPULL;
93 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
94 HAL_GPIO_Init(STSAFEA_VREG_GPIO_PORT, &GPIO_InitStruct);
95
96 /* Configure GPIO pin Output Level */
97 HAL_GPIO_WritePin(STSAFEA_VREG_GPIO_PORT, STSAFEA_VREG_PIN, GPIO_PIN_SET);
98
99 // STSAFE takes up to 50 ms to get ready, but it might take less.
100 // The first command will use the retry mechanism to cop with this delay
101 BSP_TimeDelay(50);
102
103 return BSP_OK;
104 }
105
106
107 /**
108 * @brief This function provides a delay (in milliseconds)
109 * @param none
110 * @retval 0 in case of success, an error code otherwise
111 */
BSP_TimeDelay(uint32_t msDelay)112 void BSP_TimeDelay(uint32_t msDelay)
113 {
114 /* Could be redirected to a Task Delay or to a different custom implementation */
115 uint32_t timeout = HAL_GetTick() + msDelay*40;
116 if (msDelay != HAL_MAX_DELAY)
117 {
118 while (1)
119 {
120 if (HAL_GetTick() >= timeout)
121 {
122 return;
123 }
124 }
125 }
126 }
127
128 /**
129 * @brief MX I2C2 Inititialization.
130 * @param phi2c : I2C handle.
131 * @param timing : I2C timings as described in the I2C peripheral V2 and V3.
132 * @retval Prescaler divider
133 */
MX_I2C2_Init(I2C_HandleTypeDef * phi2c,uint32_t timing)134 __weak HAL_StatusTypeDef MX_I2C2_Init(I2C_HandleTypeDef *phi2c, uint32_t timing)
135 {
136 HAL_StatusTypeDef ret = HAL_ERROR;
137
138 phi2c->Init.Timing = timing;
139 phi2c->Init.OwnAddress1 = 0;
140 phi2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
141 phi2c->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
142 phi2c->Init.OwnAddress2 = 0;
143 phi2c->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
144 phi2c->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
145
146 if (HAL_I2C_Init(phi2c) == HAL_OK)
147 {
148 if (HAL_I2CEx_ConfigAnalogFilter(phi2c, I2C_ANALOGFILTER_DISABLE) == HAL_OK)
149 {
150 if (HAL_I2CEx_ConfigDigitalFilter(phi2c, I2C_ANALOG_FILTER_DELAY_DEFAULT) == HAL_OK)
151 {
152 ret = HAL_OK;
153 }
154 }
155 }
156
157 return ret;
158 }
159
160 /**
161 * @brief Initializes I2C HAL.
162 * @retval BSP status
163 */
BSP_I2C_Init(void)164 int32_t BSP_I2C_Init(void)
165 {
166 int32_t ret = BSP_ERROR;
167 hbus_i2c->Instance = I2C2;
168
169 if (HAL_I2C_GetState(hbus_i2c) == HAL_I2C_STATE_RESET)
170 {
171 /* Init the I2C Msp */
172 I2C2_MspInit(hbus_i2c);
173
174 /* Init the I2C */
175 if (MX_I2C2_Init(hbus_i2c, BUS_I2C2_TIMING) == HAL_OK)
176 {
177 if (HAL_I2CEx_ConfigAnalogFilter(hbus_i2c, I2C_ANALOGFILTER_ENABLE) == HAL_OK)
178 {
179 ret = BSP_OK;
180 }
181 }
182 }
183 else
184 {
185 ret = BSP_OK;
186 }
187
188 return ret;
189 }
190
191 /**
192 * @brief DeInitializes I2C HAL.
193 * @retval BSP status
194 */
BSP_I2C_DeInit(void)195 int32_t BSP_I2C_DeInit(void)
196 {
197 int32_t ret = BSP_ERROR;
198 /* DeInit the I2C */
199 I2C2_MspDeInit(hbus_i2c);
200
201 /* DeInit the I2C */
202 if (HAL_I2C_DeInit(hbus_i2c) == HAL_OK)
203 {
204 ret = BSP_OK;
205 }
206
207 return ret;
208 }
209
210
211 /**
212 * @brief Send data through BUS.
213 * @param DevAddr Device address on Bus.
214 * @param pData Pointer to data buffer to write
215 * @param Length Data Length
216 * @retval BSP status
217 */
BSP_I2C_Send(uint16_t DevAddr,uint8_t * pData,uint16_t Length)218 int32_t BSP_I2C_Send(uint16_t DevAddr, uint8_t *pData, uint16_t Length)
219 {
220 int32_t ret = BSP_ERROR;
221 uint32_t hal_error;
222
223 if (HAL_I2C_Master_Transmit(hbus_i2c,
224 DevAddr,
225 pData,
226 Length,
227 BUS_I2C2_POLL_TIMEOUT) == HAL_OK)
228 {
229 ret = BSP_OK;
230 }
231 else
232 {
233 hal_error = HAL_I2C_GetError(hbus_i2c);
234 if (hal_error == HAL_I2C_ERROR_AF)
235 {
236 return BSP_NAK;
237 }
238 else
239 {
240 ret = BSP_ERROR;
241 }
242 }
243 return ret;
244 }
245
246 /**
247 * @brief Send data through BUS
248 * @param DevAddr Device address on Bus.
249 * @param pData Pointer to data buffer to read
250 * @param Length Data Length
251 * @retval BSP status
252 */
BSP_I2C_Recv(uint16_t DevAddr,uint8_t * pData,uint16_t Length)253 int32_t BSP_I2C_Recv(uint16_t DevAddr, uint8_t *pData, uint16_t Length)
254 {
255 int32_t ret = BSP_ERROR;
256 uint32_t hal_error;
257
258 if (HAL_I2C_Master_Receive(hbus_i2c,
259 DevAddr,
260 pData,
261 Length,
262 BUS_I2C2_POLL_TIMEOUT) == HAL_OK)
263 {
264 ret = BSP_OK;
265 }
266 else
267 {
268 hal_error = HAL_I2C_GetError(hbus_i2c);
269 if (hal_error == HAL_I2C_ERROR_AF)
270 {
271 return BSP_NAK;
272 }
273 else
274 {
275 ret = BSP_ERROR;
276 }
277 }
278
279 return ret;
280 }
281
282
283 /**
284 * @brief Initializes I2C MSP.
285 * @param hI2c I2C handler
286 * @retval None
287 */
I2C2_MspInit(I2C_HandleTypeDef * hI2c)288 static void I2C2_MspInit(I2C_HandleTypeDef *hI2c)
289 {
290 GPIO_InitTypeDef gpio_init;
291
292 /* Enable I2C clock */
293 BUS_I2C2_CLK_ENABLE();
294
295 /* Enable GPIO clock */
296 BUS_I2C2_SDA_GPIO_CLK_ENABLE();
297 BUS_I2C2_SCL_GPIO_CLK_ENABLE();
298
299 /* Configure I2C SDA Line */
300 gpio_init.Pin = BUS_I2C2_SDA_GPIO_PIN;
301 gpio_init.Mode = GPIO_MODE_AF_OD;
302 gpio_init.Pull = GPIO_NOPULL;
303 gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
304 gpio_init.Alternate = BUS_I2C2_SDA_GPIO_AF;
305 HAL_GPIO_Init(BUS_I2C2_SDA_GPIO_PORT, &gpio_init);
306
307 /* Configure I2C SCL Line */
308 gpio_init.Pin = BUS_I2C2_SCL_GPIO_PIN;
309 gpio_init.Mode = GPIO_MODE_AF_OD;
310 gpio_init.Pull = GPIO_NOPULL;
311 gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
312 gpio_init.Alternate = BUS_I2C2_SCL_GPIO_AF;
313 HAL_GPIO_Init(BUS_I2C2_SCL_GPIO_PORT, &gpio_init);
314
315 }
316
317 /**
318 * @brief DeInitializes I2C MSP.
319 * @param hI2c I2C handler
320 * @retval None
321 */
I2C2_MspDeInit(I2C_HandleTypeDef * hI2c)322 static void I2C2_MspDeInit(I2C_HandleTypeDef *hI2c)
323 {
324 /* Disable I2C clock */
325 __HAL_RCC_I2C2_CLK_DISABLE();
326
327 /* DeInitialize peripheral GPIOs */
328 HAL_GPIO_DeInit(BUS_I2C2_SDA_GPIO_PORT, BUS_I2C2_SDA_GPIO_PIN);
329 HAL_GPIO_DeInit(BUS_I2C2_SCL_GPIO_PORT, BUS_I2C2_SCL_GPIO_PIN);
330
331 }
332
333