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>&copy; 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