aboutsummaryrefslogtreecommitdiff
path: root/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_conf_template.h
blob: 30cceaf14f090098d86eca4a5a1d172dafcc5b36 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
/**
  ******************************************************************************
  * @file    stm32f4xx_hal_conf_template.h
  * @author  MCD Application Team
  * @version V1.4.1
  * @date    09-October-2015
  * @brief   HAL configuration template file. 
  *          This file should be copied to the application folder and renamed
  *          to stm32f4xx_hal_conf.h.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */ 

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_HAL_CONF_H
#define __STM32F4xx_HAL_CONF_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

/* ########################## Module Selection ############################## */
/**
  * @brief This is the list of modules to be used in the HAL driver 
  */
#define HAL_MODULE_ENABLED  
#define HAL_ADC_MODULE_ENABLED  
#define HAL_CAN_MODULE_ENABLED  
#define HAL_CRC_MODULE_ENABLED  
#define HAL_CEC_MODULE_ENABLED
#define HAL_CRYP_MODULE_ENABLED  
#define HAL_DAC_MODULE_ENABLED  
#define HAL_DCMI_MODULE_ENABLED 
#define HAL_DMA_MODULE_ENABLED
#define HAL_DMA2D_MODULE_ENABLED 
#define HAL_ETH_MODULE_ENABLED 
#define HAL_FLASH_MODULE_ENABLED 
#define HAL_NAND_MODULE_ENABLED
#define HAL_NOR_MODULE_ENABLED
#define HAL_PCCARD_MODULE_ENABLED
#define HAL_SRAM_MODULE_ENABLED
#define HAL_SDRAM_MODULE_ENABLED
#define HAL_HASH_MODULE_ENABLED  
#define HAL_GPIO_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
#define HAL_I2S_MODULE_ENABLED   
#define HAL_IWDG_MODULE_ENABLED 
#define HAL_LTDC_MODULE_ENABLED 
#define HAL_DSI_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_QSPI_MODULE_ENABLED   
#define HAL_RCC_MODULE_ENABLED 
#define HAL_RNG_MODULE_ENABLED   
#define HAL_RTC_MODULE_ENABLED
#define HAL_SAI_MODULE_ENABLED   
#define HAL_SD_MODULE_ENABLED  
#define HAL_SPI_MODULE_ENABLED   
#define HAL_TIM_MODULE_ENABLED   
#define HAL_UART_MODULE_ENABLED 
#define HAL_USART_MODULE_ENABLED 
#define HAL_IRDA_MODULE_ENABLED 
#define HAL_SMARTCARD_MODULE_ENABLED 
#define HAL_WWDG_MODULE_ENABLED  
#define HAL_CORTEX_MODULE_ENABLED
#define HAL_PCD_MODULE_ENABLED
#define HAL_HCD_MODULE_ENABLED
#define HAL_FMPI2C_MODULE_ENABLED
#define HAL_SPDIFRX_MODULE_ENABLED
#define HAL_LPTIM_MODULE_ENABLED

/* ########################## HSE/HSI Values adaptation ##################### */
/**
  * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
  *        This value is used by the RCC HAL module to compute the system frequency
  *        (when HSE is used as system clock source, directly or through the PLL).  
  */
#if !defined  (HSE_VALUE) 
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */

#if !defined  (HSE_STARTUP_TIMEOUT)
  #define HSE_STARTUP_TIMEOUT    ((uint32_t)5000)   /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */

/**
  * @brief Internal High Speed oscillator (HSI) value.
  *        This value is used by the RCC HAL module to compute the system frequency
  *        (when HSI is used as system clock source, directly or through the PLL). 
  */
#if !defined  (HSI_VALUE)
  #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */

/**
  * @brief Internal Low Speed oscillator (LSI) value.
  */
#if !defined  (LSI_VALUE) 
 #define LSI_VALUE  ((uint32_t)32000)       /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */                      /*!< Value of the Internal Low Speed oscillator in Hz
                                             The real value may vary depending on the variations
                                             in voltage and temperature.*/
/**
  * @brief External Low Speed oscillator (LSE) value.
  */
#if !defined  (LSE_VALUE)
 #define LSE_VALUE  ((uint32_t)32768)    /*!< Value of the External Low Speed oscillator in Hz */
#endif /* LSE_VALUE */

/**
  * @brief External clock source for I2S peripheral
  *        This value is used by the I2S HAL module to compute the I2S clock source 
  *        frequency, this source is inserted directly through I2S_CKIN pad. 
  */
#if !defined  (EXTERNAL_CLOCK_VALUE)
  #define EXTERNAL_CLOCK_VALUE    ((uint32_t)12288000) /*!< Value of the Internal oscillator in Hz*/
#endif /* EXTERNAL_CLOCK_VALUE */

/* Tip: To avoid modifying this file each time you need to use different HSE,
   ===  you can define the HSE value in your toolchain compiler preprocessor. */

/* ########################### System Configuration ######################### */
/**
  * @brief This is the HAL system configuration section
  */     
#define  VDD_VALUE                    ((uint32_t)3300) /*!< Value of VDD in mv */
#define  TICK_INT_PRIORITY            ((uint32_t)0x0F) /*!< tick interrupt priority */
#define  USE_RTOS                     0
#define  PREFETCH_ENABLE              1
#define  INSTRUCTION_CACHE_ENABLE     1
#define  DATA_CACHE_ENABLE            1

/* ########################## Assert Selection ############################## */
/**
  * @brief Uncomment the line below to expanse the "assert_param" macro in the 
  *        HAL drivers code
  */
/* #define USE_FULL_ASSERT    1 */

/* ################## Ethernet peripheral configuration ##################### */

/* Section 1 : Ethernet peripheral configuration */

/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
#define MAC_ADDR0   2
#define MAC_ADDR1   0
#define MAC_ADDR2   0
#define MAC_ADDR3   0
#define MAC_ADDR4   0
#define MAC_ADDR5   0

/* Definition of the Ethernet driver buffers size and count */   
#define ETH_RX_BUF_SIZE                ETH_MAX_PACKET_SIZE /* buffer size for receive               */
#define ETH_TX_BUF_SIZE                ETH_MAX_PACKET_SIZE /* buffer size for transmit              */
#define ETH_RXBUFNB                    ((uint32_t)4)       /* 4 Rx buffers of size ETH_RX_BUF_SIZE  */
#define ETH_TXBUFNB                    ((uint32_t)4)       /* 4 Tx buffers of size ETH_TX_BUF_SIZE  */

/* Section 2: PHY configuration section */

/* DP83848 PHY Address*/ 
#define DP83848_PHY_ADDRESS             0x01
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ 
#define PHY_RESET_DELAY                 ((uint32_t)0x000000FF)
/* PHY Configuration delay */
#define PHY_CONFIG_DELAY                ((uint32_t)0x00000FFF)

#define PHY_READ_TO                     ((uint32_t)0x0000FFFF)
#define PHY_WRITE_TO                    ((uint32_t)0x0000FFFF)

/* Section 3: Common PHY Registers */

#define PHY_BCR                         ((uint16_t)0x00)    /*!< Transceiver Basic Control Register   */
#define PHY_BSR                         ((uint16_t)0x01)    /*!< Transceiver Basic Status Register    */
 
#define PHY_RESET                       ((uint16_t)0x8000)  /*!< PHY Reset */
#define PHY_LOOPBACK                    ((uint16_t)0x4000)  /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M             ((uint16_t)0x2100)  /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M             ((uint16_t)0x2000)  /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M              ((uint16_t)0x0100)  /*!< Set the full-duplex mode at 10 Mb/s  */
#define PHY_HALFDUPLEX_10M              ((uint16_t)0x0000)  /*!< Set the half-duplex mode at 10 Mb/s  */
#define PHY_AUTONEGOTIATION             ((uint16_t)0x1000)  /*!< Enable auto-negotiation function     */
#define PHY_RESTART_AUTONEGOTIATION     ((uint16_t)0x0200)  /*!< Restart auto-negotiation function    */
#define PHY_POWERDOWN                   ((uint16_t)0x0800)  /*!< Select the power down mode           */
#define PHY_ISOLATE                     ((uint16_t)0x0400)  /*!< Isolate PHY from MII                 */

#define PHY_AUTONEGO_COMPLETE           ((uint16_t)0x0020)  /*!< Auto-Negotiation process completed   */
#define PHY_LINKED_STATUS               ((uint16_t)0x0004)  /*!< Valid link established               */
#define PHY_JABBER_DETECTION            ((uint16_t)0x0002)  /*!< Jabber condition detected            */
  
/* Section 4: Extended PHY Registers */

#define PHY_SR                          ((uint16_t)0x10)    /*!< PHY status register Offset                      */
#define PHY_MICR                        ((uint16_t)0x11)    /*!< MII Interrupt Control Register                  */
#define PHY_MISR                        ((uint16_t)0x12)    /*!< MII Interrupt Status and Misc. Control Register */
 
#define PHY_LINK_STATUS                 ((uint16_t)0x0001)  /*!< PHY Link mask                                   */
#define PHY_SPEED_STATUS                ((uint16_t)0x0002)  /*!< PHY Speed mask                                  */
#define PHY_DUPLEX_STATUS               ((uint16_t)0x0004)  /*!< PHY Duplex mask                                 */

#define PHY_MICR_INT_EN                 ((uint16_t)0x0002)  /*!< PHY Enable interrupts                           */
#define PHY_MICR_INT_OE                 ((uint16_t)0x0001)  /*!< PHY Enable output interrupt events              */

#define PHY_MISR_LINK_INT_EN            ((uint16_t)0x0020)  /*!< Enable Interrupt on change of link status       */
#define PHY_LINK_INTERRUPT              ((uint16_t)0x2000)  /*!< PHY link status interrupt mask                  */

/* Includes ------------------------------------------------------------------*/
/**
  * @brief Include module's header file 
  */

#ifdef HAL_RCC_MODULE_ENABLED
  #include "stm32f4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */

#ifdef HAL_GPIO_MODULE_ENABLED
  #include "stm32f4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */

#ifdef HAL_DMA_MODULE_ENABLED
  #include "stm32f4xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
   
#ifdef HAL_CORTEX_MODULE_ENABLED
  #include "stm32f4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */

#ifdef HAL_ADC_MODULE_ENABLED
  #include "stm32f4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */

#ifdef HAL_CAN_MODULE_ENABLED
  #include "stm32f4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */

#ifdef HAL_CRC_MODULE_ENABLED
  #include "stm32f4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */

#ifdef HAL_CRYP_MODULE_ENABLED
  #include "stm32f4xx_hal_cryp.h" 
#endif /* HAL_CRYP_MODULE_ENABLED */

#ifdef HAL_DMA2D_MODULE_ENABLED
  #include "stm32f4xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */

#ifdef HAL_DAC_MODULE_ENABLED
  #include "stm32f4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */

#ifdef HAL_DCMI_MODULE_ENABLED
  #include "stm32f4xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */

#ifdef HAL_ETH_MODULE_ENABLED
  #include "stm32f4xx_hal_eth.h"
#endif /* HAL_ETH_MODULE_ENABLED */

#ifdef HAL_FLASH_MODULE_ENABLED
  #include "stm32f4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
 
#ifdef HAL_SRAM_MODULE_ENABLED
  #include "stm32f4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */

#ifdef HAL_NOR_MODULE_ENABLED
  #include "stm32f4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */

#ifdef HAL_NAND_MODULE_ENABLED
  #include "stm32f4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */

#ifdef HAL_PCCARD_MODULE_ENABLED
  #include "stm32f4xx_hal_pccard.h"
#endif /* HAL_PCCARD_MODULE_ENABLED */ 
  
#ifdef HAL_SDRAM_MODULE_ENABLED
  #include "stm32f4xx_hal_sdram.h"
#endif /* HAL_SDRAM_MODULE_ENABLED */      

#ifdef HAL_HASH_MODULE_ENABLED
 #include "stm32f4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */

#ifdef HAL_I2C_MODULE_ENABLED
 #include "stm32f4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */

#ifdef HAL_I2S_MODULE_ENABLED
 #include "stm32f4xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */

#ifdef HAL_IWDG_MODULE_ENABLED
 #include "stm32f4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */

#ifdef HAL_LTDC_MODULE_ENABLED
 #include "stm32f4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */

#ifdef HAL_PWR_MODULE_ENABLED
 #include "stm32f4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */

#ifdef HAL_RNG_MODULE_ENABLED
 #include "stm32f4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */

#ifdef HAL_RTC_MODULE_ENABLED
 #include "stm32f4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */

#ifdef HAL_SAI_MODULE_ENABLED
 #include "stm32f4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */

#ifdef HAL_SD_MODULE_ENABLED
 #include "stm32f4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */

#ifdef HAL_SPI_MODULE_ENABLED
 #include "stm32f4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */

#ifdef HAL_TIM_MODULE_ENABLED
 #include "stm32f4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */

#ifdef HAL_UART_MODULE_ENABLED
 #include "stm32f4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */

#ifdef HAL_USART_MODULE_ENABLED
 #include "stm32f4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */

#ifdef HAL_IRDA_MODULE_ENABLED
 #include "stm32f4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */

#ifdef HAL_SMARTCARD_MODULE_ENABLED
 #include "stm32f4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */

#ifdef HAL_WWDG_MODULE_ENABLED
 #include "stm32f4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */

#ifdef HAL_PCD_MODULE_ENABLED
 #include "stm32f4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */

#ifdef HAL_HCD_MODULE_ENABLED
 #include "stm32f4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
   
#ifdef HAL_DSI_MODULE_ENABLED
 #include "stm32f4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */

#ifdef HAL_QSPI_MODULE_ENABLED
 #include "stm32f4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */

#ifdef HAL_CEC_MODULE_ENABLED
 #include "stm32f4xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */

#ifdef HAL_FMPI2C_MODULE_ENABLED
 #include "stm32f4xx_hal_fmpi2c.h"
#endif /* HAL_FMPI2C_MODULE_ENABLED */

#ifdef HAL_SPDIFRX_MODULE_ENABLED
 #include "stm32f4xx_hal_spdifrx.h"
#endif /* HAL_SPDIFRX_MODULE_ENABLED */

#ifdef HAL_LPTIM_MODULE_ENABLED
 #include "stm32f4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */

/* Exported macro ------------------------------------------------------------*/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param  expr: If expr is false, it calls assert_failed function
  *         which reports the name of the source file and the source
  *         line number of the call that failed. 
  *         If expr is true, it returns no value.
  * @retval None
  */
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
  void assert_failed(uint8_t* file, uint32_t line);
#else
  #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */


#ifdef __cplusplus
}
#endif

#endif /* __STM32F4xx_HAL_CONF_H */
 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
f='#n1504'>1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858
/**
  ******************************************************************************
  * @file    stm32f4xx_hal_hash.c
  * @author  MCD Application Team
  * @version V1.4.1
  * @date    09-October-2015
  * @brief   HASH HAL module driver.
  *          This file provides firmware functions to manage the following 
  *          functionalities of the HASH peripheral:
  *           + Initialization and de-initialization functions
  *           + HASH/HMAC Processing functions by algorithm using polling mode
  *           + HASH/HMAC functions by algorithm using interrupt mode
  *           + HASH/HMAC functions by algorithm using DMA mode
  *           + Peripheral State functions
  *         
  @verbatim
  ==============================================================================
                     ##### How to use this driver #####
  ==============================================================================
    [..]
    The HASH HAL driver can be used as follows:
    (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
        (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
        (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
            (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
            (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
            (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
        (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
            (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
            (+++) Configure and enable one DMA stream one for managing data transfer from
                memory to peripheral (input stream). Managing data transfer from
                peripheral to memory can be performed only using CPU
            (+++) Associate the initialized DMA handle to the HASH DMA handle
                using  __HAL_LINKDMA()
            (+++) Configure the priority and enable the NVIC for the transfer complete
                interrupt on the DMA Stream using HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
    (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
        (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
        (##) For HMAC, the encryption key.
        (##) For HMAC, the key size used for encryption.
    (#)Three processing functions are available:
        (##) Polling mode: processing APIs are blocking functions
             i.e. they process the data and wait till the digest computation is finished
             e.g. HAL_HASH_SHA1_Start()
        (##) Interrupt mode: encryption and decryption APIs are not blocking functions
                i.e. they process the data under interrupt
                e.g. HAL_HASH_SHA1_Start_IT()
        (##) DMA mode: processing APIs are not blocking functions and the CPU is
             not used for data transfer i.e. the data transfer is ensured by DMA
                e.g. HAL_HASH_SHA1_Start_DMA()
    (#)When the processing function is called at first time after HAL_HASH_Init()
       the HASH peripheral is initialized and processes the buffer in input.
       After that, the digest computation is started.
       When processing multi-buffer use the accumulate function to write the
       data in the peripheral without starting the digest computation. In last 
       buffer use the start function to input the last buffer ans start the digest
       computation.
       (##) e.g. HAL_HASH_SHA1_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
       (##) write (n-1)th data buffer in the peripheral without starting the digest computation
       (##) HAL_HASH_SHA1_Start() : write (n)th data buffer in the peripheral and start the digest computation
    (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
    (#)In case of using DMA, call the DMA start processing e.g. HAL_HASH_SHA1_Start_DMA().
       After that, call the finish function in order to get the digest value
       e.g. HAL_HASH_SHA1_Finish()
    (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.

  @endverbatim
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

/** @addtogroup STM32F4xx_HAL_Driver
  * @{
  */

/** @defgroup HASH HASH
  * @brief HASH HAL module driver.
  * @{
  */

#ifdef HAL_HASH_MODULE_ENABLED

#if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F479xx)

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup HASH_Private_Functions HASH Private Functions
  * @{
  */
static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
static void HASH_DMAError(DMA_HandleTypeDef *hdma);
static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
/**
  * @}
  */
  
/* Private functions ---------------------------------------------------------*/
/** @addtogroup HASH_Private_Functions
  * @{
  */

/**
  * @brief  DMA HASH Input Data complete callback. 
  * @param  hdma: DMA handle
  * @retval None
  */
static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
{
  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  uint32_t inputaddr = 0;
  uint32_t buffersize = 0;
  
  if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
  {
    /* Disable the DMA transfer */
    HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
    
    /* Change HASH peripheral state */
    hhash->State = HAL_HASH_STATE_READY;
    
    /* Call Input data transfer complete callback */
    HAL_HASH_InCpltCallback(hhash);
  }
  else
  {
    /* Increment Interrupt counter */
    hhash->HashInCount++;
    /* Disable the DMA transfer before starting the next transfer */
    HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
    
    if(hhash->HashInCount <= 2)
    {
      /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
      if(hhash->HashInCount == 1)
      {
        inputaddr = (uint32_t)hhash->pHashInBuffPtr;
        buffersize = hhash->HashBuffSize;
      }
      /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
      else if(hhash->HashInCount == 2)
      {
        inputaddr = (uint32_t)hhash->Init.pKey;
        buffersize = hhash->Init.KeySize;
      }
      /* Configure the number of valid bits in last word of the message */
      MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8 * (buffersize % 4));
            
      /* Set the HASH DMA transfer complete */
      hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
      
      /* Enable the DMA In DMA Stream */
      HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
      
      /* Enable DMA requests */
      HASH->CR |= (HASH_CR_DMAE);
    }
    else
    {
      /* Disable the DMA transfer */
      HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
      
      /* Reset the InCount */
      hhash->HashInCount = 0;
      
      /* Change HASH peripheral state */
      hhash->State = HAL_HASH_STATE_READY;
      
      /* Call Input data transfer complete callback */
      HAL_HASH_InCpltCallback(hhash);
    }
  }
}

/**
  * @brief  DMA HASH communication error callback. 
  * @param  hdma: DMA handle
  * @retval None
  */
static void HASH_DMAError(DMA_HandleTypeDef *hdma)
{
  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  hhash->State= HAL_HASH_STATE_READY;
  HAL_HASH_ErrorCallback(hhash);
}

/**
  * @brief  Writes the input buffer in data register.
  * @param  pInBuffer: Pointer to input buffer
  * @param  Size: The size of input buffer
  * @retval None
  */
static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t buffercounter;
  uint32_t inputaddr = (uint32_t) pInBuffer;
  
  for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
  {
    HASH->DIN = *(uint32_t*)inputaddr;
    inputaddr+=4;
  }
}

/**
  * @brief  Provides the message digest result.
  * @param  pMsgDigest: Pointer to the message digest
  * @param  Size: The size of the message digest in bytes
  * @retval None
  */
static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
{
  uint32_t msgdigest = (uint32_t)pMsgDigest;
  
  switch(Size)
  {
  case 16:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
    break;
  case 20:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
    break;
  case 28:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
    break;
  case 32:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
    msgdigest+=4;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
    break;
  default:
    break;
  }
}

/**
  * @}
  */

/* Exported functions --------------------------------------------------------*/
/** @addtogroup HASH_Exported_Functions
  * @{
  */
  

/** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions 
 *  @brief    Initialization and Configuration functions. 
 *
@verbatim    
 ===============================================================================
              ##### Initialization and de-initialization functions #####
 ===============================================================================
    [..]  This section provides functions allowing to:
      (+) Initialize the HASH according to the specified parameters 
          in the HASH_InitTypeDef and creates the associated handle.
      (+) DeInitialize the HASH peripheral.
      (+) Initialize the HASH MSP.
      (+) DeInitialize HASH MSP. 
 
@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH according to the specified parameters in the
            HASH_HandleTypeDef and creates the associated handle.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
{
  /* Check the hash handle allocation */
  if(hhash == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
   
  if(hhash->State == HAL_HASH_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    hhash->Lock = HAL_UNLOCKED;
    /* Init the low level hardware */
    HAL_HASH_MspInit(hhash);
  }
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Reset HashInCount, HashBuffSize and HashITCounter */
  hhash->HashInCount = 0;
  hhash->HashBuffSize = 0;
  hhash->HashITCounter = 0;
  
  /* Set the data type */
  HASH->CR |= (uint32_t) (hhash->Init.DataType);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;
  
  /* Set the default HASH phase */
  hhash->Phase = HAL_HASH_PHASE_READY;
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  DeInitializes the HASH peripheral.
  * @note   This API must be called before starting a new processing. 
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
{ 
  /* Check the HASH handle allocation */
  if(hhash == NULL)
  {
    return HAL_ERROR;
  }
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Set the default HASH phase */
  hhash->Phase = HAL_HASH_PHASE_READY;
  
  /* Reset HashInCount, HashBuffSize and HashITCounter */
  hhash->HashInCount = 0;
  hhash->HashBuffSize = 0;
  hhash->HashITCounter = 0;
  
  /* DeInit the low level hardware */
  HAL_HASH_MspDeInit(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_RESET;  

  /* Release Lock */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH MSP.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval None
  */
__weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
{
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_HASH_MspInit could be implemented in the user file
   */
}

/**
  * @brief  DeInitializes HASH MSP.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval None
  */
__weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
{
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_HASH_MspDeInit could be implemented in the user file
   */
}

/**
  * @brief  Input data transfer complete callback.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval None
  */
 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
{
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_HASH_InCpltCallback could be implemented in the user file
   */ 
}

/**
  * @brief  Data transfer Error callback.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval None
  */
 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
{
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_HASH_ErrorCallback could be implemented in the user file
   */ 
}

/**
  * @brief  Digest computation complete callback. It is used only with interrupt.
  * @note   This callback is not relevant with DMA.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval None
  */
 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
{
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_HASH_DgstCpltCallback could be implemented in the user file
   */ 
}

/**
  * @}
  */

/** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode 
 *  @brief   processing functions using polling mode 
 *
@verbatim   
 ===============================================================================
              ##### HASH processing using polling mode functions#####
 ===============================================================================  
    [..]  This section provides functions allowing to calculate in polling mode
          the hash value using one of the following algorithms:
      (+) MD5
      (+) SHA1

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
            The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
  *          and appending the input buffer is no more possible.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
  * @param  Timeout: Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0;
  
  /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Write input buffer in data register */
  HASH_WriteData(pInBuffer, Size);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();
  
  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Read the message digest */
  HASH_GetDigest(pOutBuffer, 16);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;
   
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
  *          and appending the input buffer is no more possible.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{  
  /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Write input buffer in data register */
  HASH_WriteData(pInBuffer, Size);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
            The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).  
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @param  Timeout: Timeout value  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0;   

  /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Write input buffer in data register */
  HASH_WriteData(pInBuffer, Size);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();

  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
        {
          /* Change state */
          hhash->State = HAL_HASH_STATE_TIMEOUT;
          
          /* Process Unlocked */
          __HAL_UNLOCK(hhash);
          
          return HAL_TIMEOUT;
        }
      }
    }
  
  /* Read the message digest */
  HASH_GetDigest(pOutBuffer, 20);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @note  Input buffer size in bytes must be a multiple of 4 otherwise the digest computation is corrupted.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  /* Check the parameters */
  assert_param(IS_HASH_SHA1_BUFFER_SIZE(Size));

  /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Write input buffer in data register */
  HASH_WriteData(pInBuffer, Size);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */

/** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
 *  @brief   processing functions using interrupt mode. 
 *
@verbatim   
 ===============================================================================
              ##### HASH processing using interrupt mode functions #####
 ===============================================================================  
    [..]  This section provides functions allowing to calculate in interrupt mode
          the hash value using one of the following algorithms:
      (+) MD5
      (+) SHA1

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
  *         The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).   
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
{
  uint32_t inputaddr;
  uint32_t outputaddr;
  uint32_t buffercounter;
  uint32_t inputcounter;
  
  /* Process Locked */
  __HAL_LOCK(hhash);
  
  if(hhash->State == HAL_HASH_STATE_READY)
  {
    /* Change the HASH state */
    hhash->State = HAL_HASH_STATE_BUSY;
    
    hhash->HashInCount = Size;
    hhash->pHashInBuffPtr = pInBuffer;
    hhash->pHashOutBuffPtr = pOutBuffer;
    
    /* Check if initialization phase has already been performed */
    if(hhash->Phase == HAL_HASH_PHASE_READY)
    {
      /* Select the SHA1 mode */
      HASH->CR |= HASH_ALGOSELECTION_MD5;
      /* Reset the HASH processor core, so that the HASH will be ready to compute 
         the message digest of a new message */
      HASH->CR |= HASH_CR_INIT;
    }
    /* Reset interrupt counter */
    hhash->HashITCounter = 0;
    
    /* Set the phase */
    hhash->Phase = HAL_HASH_PHASE_PROCESS;
    
    /* Process Unlocked */
    __HAL_UNLOCK(hhash);
    
    /* Enable Interrupts */
    HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
    
    /* Return function status */
    return HAL_OK;
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
  {
    outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
    /* Read the Output block from the Output FIFO */
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
    outputaddr+=4;
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
    outputaddr+=4;
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
    outputaddr+=4;
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
    
    if(hhash->HashInCount == 0)
    {
      /* Disable Interrupts */
      HASH->IMR = 0;
      /* Change the HASH state */
      hhash->State = HAL_HASH_STATE_READY;
      /* Call digest computation complete callback */
      HAL_HASH_DgstCpltCallback(hhash);
      
      /* Process Unlocked */
      __HAL_UNLOCK(hhash);
      
      /* Return function status */
      return HAL_OK;
    }
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
  {
    if(hhash->HashInCount >= 68)
    {
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4;
      }
      if(hhash->HashITCounter == 0)
      {
        HASH->DIN = *(uint32_t*)inputaddr;

        if(hhash->HashInCount >= 68)
        {
          /* Decrement buffer counter */
          hhash->HashInCount -= 68;
          hhash->pHashInBuffPtr+= 68;
        }
        else
        {
          hhash->HashInCount = 0;
          hhash->pHashInBuffPtr+= hhash->HashInCount;
        }
        /* Set Interrupt counter */
        hhash->HashITCounter = 1;
      }
      else
      {
        /* Decrement buffer counter */
        hhash->HashInCount -= 64;
        hhash->pHashInBuffPtr+= 64;
      }
    }
    else
    {
      /* Get the buffer address */
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Get the buffer counter */
      inputcounter = hhash->HashInCount;
      /* Disable Interrupts */
      HASH->IMR &= ~(HASH_IT_DINI);
      /* Configure the number of valid bits in last word of the message */
      __HAL_HASH_SET_NBVALIDBITS(inputcounter);
      
      if((inputcounter > 4) && (inputcounter%4))
      {
        inputcounter = (inputcounter+4-inputcounter%4);
      }
      else if ((inputcounter < 4) && (inputcounter != 0))
      {
        inputcounter = 4;
      }
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4;
      }
      /* Start the digest calculation */
      __HAL_HASH_START_DIGEST();
      /* Reset buffer counter */
      hhash->HashInCount = 0;
      /* Call Input data transfer complete callback */
      HAL_HASH_InCpltCallback(hhash);
    }
  }
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
  *         The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed). 
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
{
  uint32_t inputaddr;
  uint32_t outputaddr;
  uint32_t buffercounter;
  uint32_t inputcounter;
  
  /* Process Locked */
  __HAL_LOCK(hhash);
  
  if(hhash->State == HAL_HASH_STATE_READY)
  {
    /* Change the HASH state */
    hhash->State = HAL_HASH_STATE_BUSY;
    
    hhash->HashInCount = Size;
    hhash->pHashInBuffPtr = pInBuffer;
    hhash->pHashOutBuffPtr = pOutBuffer;
    
    /* Check if initialization phase has already been performed */
    if(hhash->Phase == HAL_HASH_PHASE_READY)
    {
      /* Select the SHA1 mode */
      HASH->CR |= HASH_ALGOSELECTION_SHA1;
      /* Reset the HASH processor core, so that the HASH will be ready to compute 
         the message digest of a new message */
      HASH->CR |= HASH_CR_INIT;
    }
    /* Reset interrupt counter */
    hhash->HashITCounter = 0;
    
    /* Set the phase */
    hhash->Phase = HAL_HASH_PHASE_PROCESS;
    
    /* Process Unlocked */
    __HAL_UNLOCK(hhash);
    
    /* Enable Interrupts */
    HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
    
    /* Return function status */
    return HAL_OK;
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
  {
    outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
    /* Read the Output block from the Output FIFO */
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
    outputaddr+=4;
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
    outputaddr+=4;
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
    outputaddr+=4;
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
    outputaddr+=4;
    *(uint32_t*)(outputaddr) = __REV(HASH->HR[4]);
    if(hhash->HashInCount == 0)
    {
      /* Disable Interrupts */
      HASH->IMR = 0;
      /* Change the HASH state */
      hhash->State = HAL_HASH_STATE_READY;
      /* Call digest computation complete callback */
      HAL_HASH_DgstCpltCallback(hhash);
      
      /* Process Unlocked */
      __HAL_UNLOCK(hhash);
      
      /* Return function status */
      return HAL_OK;
    }
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
  {
    if(hhash->HashInCount >= 68)
    {
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4;
      }
      if(hhash->HashITCounter == 0)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        if(hhash->HashInCount >= 68)
        {
          /* Decrement buffer counter */
          hhash->HashInCount -= 68;
          hhash->pHashInBuffPtr+= 68;
        }
        else
        {
          hhash->HashInCount = 0;
          hhash->pHashInBuffPtr+= hhash->HashInCount;
        }
        /* Set Interrupt counter */
        hhash->HashITCounter = 1;
      }
      else
      {
        /* Decrement buffer counter */
        hhash->HashInCount -= 64;
        hhash->pHashInBuffPtr+= 64;
      }
    }
    else
    {
      /* Get the buffer address */
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Get the buffer counter */
      inputcounter = hhash->HashInCount;
      /* Disable Interrupts */
      HASH->IMR &= ~(HASH_IT_DINI);
      /* Configure the number of valid bits in last word of the message */
      __HAL_HASH_SET_NBVALIDBITS(inputcounter);
      
      if((inputcounter > 4) && (inputcounter%4))
      {
        inputcounter = (inputcounter+4-inputcounter%4);
      }
      else if ((inputcounter < 4) && (inputcounter != 0))
      {
        inputcounter = 4;
      }
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4;
      }
      /* Start the digest calculation */
      __HAL_HASH_START_DIGEST();
      /* Reset buffer counter */
      hhash->HashInCount = 0;
      /* Call Input data transfer complete callback */
      HAL_HASH_InCpltCallback(hhash);
    }
  }
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief This function handles HASH interrupt request.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval None
  */
void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
{
  switch(HASH->CR & HASH_CR_ALGO)
  {
    case HASH_ALGOSELECTION_MD5:
       HAL_HASH_MD5_Start_IT(hhash, NULL, 0, NULL);
    break;
    
    case HASH_ALGOSELECTION_SHA1:
      HAL_HASH_SHA1_Start_IT(hhash, NULL, 0, NULL);
    break;
    
    default:
    break;
  }
}

/**
  * @}
  */

/** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
 *  @brief   processing functions using DMA mode. 
 *
@verbatim   
 ===============================================================================
              ##### HASH processing using DMA mode functions #####
 ===============================================================================  
    [..]  This section provides functions allowing to calculate in DMA mode
          the hash value using one of the following algorithms:
      (+) MD5
      (+) SHA1

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in MD5 mode then enables DMA to
            control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr  = (uint32_t)pInBuffer;
  
   /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute 
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
  }
   
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
    
  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASH_DMAError;
  
  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
  
  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);
  
   /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Returns the computed digest in MD5 mode
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
  * @param  Timeout: Timeout value  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0;   
  
   /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Get tick */
  tickstart = HAL_GetTick();

  while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Read the message digest */
  HASH_GetDigest(pOutBuffer, 16);
      
  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_READY;
  
   /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA1 mode then enables DMA to
            control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr  = (uint32_t)pInBuffer;
  
   /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute 
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA1;
    HASH->CR |= HASH_CR_INIT;
  }
  
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASH_DMAError;
  
  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
  
  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);
  
   /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Returns the computed digest in SHA1 mode.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.  
  * @param  Timeout: Timeout value    
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0;   
  
   /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Get tick */
  tickstart = HAL_GetTick();
  while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Read the message digest */
  HASH_GetDigest(pOutBuffer, 20);
  
  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_READY;
  
   /* Process UnLock */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}


/**
  * @}
  */

/** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode 
 *  @brief   HMAC processing functions using polling mode . 
 *
@verbatim   
 ===============================================================================
              ##### HMAC processing using polling mode functions #####
 ===============================================================================  
    [..]  This section provides functions allowing to calculate in polling mode
          the HMAC value using one of the following algorithms:
      (+) MD5
      (+) SHA1

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in HMAC MD5 mode
  *         then processes pInBuffer. The digest is available in pOutBuffer
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @param  Timeout: Timeout value  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0;   
  
   /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64)
    {
      /* Select the HMAC MD5 mode */
      HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
    }
    else
    {
      /* Select the HMAC MD5 mode */
      HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
    }
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /************************** STEP 1 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
  
  /* Write input buffer in data register */
  HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();

  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 2 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Write input buffer in data register */
  HASH_WriteData(pInBuffer, Size);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();
  
  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 3 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
  
  /* Write input buffer in data register */
  HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();
  
  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Read the message digest */
  HASH_GetDigest(pOutBuffer, 16);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
  *         then processes pInBuffer. The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param   Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @param  Timeout: Timeout value  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0;   
  
  /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64)
    {
      /* Select the HMAC SHA1 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
    }
    else
    {
      /* Select the HMAC SHA1 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
    }
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /************************** STEP 1 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
  
  /* Write input buffer in data register */
  HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();
  
  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 2 ******************************************/
  /* Configure the number of valid bits in last word of the message */  
  __HAL_HASH_SET_NBVALIDBITS(Size);
  
  /* Write input buffer in data register */
  HASH_WriteData(pInBuffer, Size);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();
  
  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 3 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
  
  /* Write input buffer in data register */
  HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
  
  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();
  
  /* Get tick */
  tickstart = HAL_GetTick();

  while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;
        
        /* Process Unlocked */
        __HAL_UNLOCK(hhash);
        
        return HAL_TIMEOUT;
      }
    }
  }
  /* Read the message digest */
  HASH_GetDigest(pOutBuffer, 20);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */

/** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode 
 *  @brief   HMAC processing functions using DMA mode . 
 *
@verbatim   
 ===============================================================================
                ##### HMAC processing using DMA mode functions #####
 ===============================================================================  
    [..]  This section provides functions allowing to calculate in DMA mode
          the HMAC value using one of the following algorithms:
      (+) MD5
      (+) SHA1

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in HMAC MD5 mode
  *         then enables DMA to control data transfer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr  = 0;
  
   /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Save buffer pointer and size in handle */
  hhash->pHashInBuffPtr = pInBuffer;
  hhash->HashBuffSize = Size;
  hhash->HashInCount = 0;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64)
    {
      /* Select the HMAC MD5 mode */
      HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
    }
    else
    {
      /* Select the HMAC MD5 mode */
      HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
    }
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
  
  /* Get the key address */
  inputaddr = (uint32_t)(hhash->Init.pKey);
  
  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASH_DMAError;
  
  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
  *         then enables DMA to control data transfer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr  = 0;
  
  /* Process Locked */
  __HAL_LOCK(hhash);
  
  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;
  
  /* Save buffer pointer and size in handle */
  hhash->pHashInBuffPtr = pInBuffer;
  hhash->HashBuffSize = Size;
  hhash->HashInCount = 0;
  
  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64)
    {
      /* Select the HMAC SHA1 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
    }
    else
    {
      /* Select the HMAC SHA1 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
    }
  }
  
  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;
  
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
  
  /* Get the key address */
  inputaddr = (uint32_t)(hhash->Init.pKey);
  
  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASH_DMAError;
  
  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);
  
  /* Process Unlocked */
  __HAL_UNLOCK(hhash);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */

/** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions 
 *  @brief   Peripheral State functions. 
 *
@verbatim   
 ===============================================================================
                      ##### Peripheral State functions #####
 ===============================================================================  
    [..]
    This subsection permits to get in run-time the status of the peripheral.

@endverbatim
  * @{
  */

/**
  * @brief return the HASH state
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval HAL state
  */
HAL_HASH_STATETypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
{
  return hhash->State;
}

/**
  * @}
  */

/**
  * @}
  */

#endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx || STM32F479xx */
#endif /* HAL_HASH_MODULE_ENABLED */
/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/